PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | class/class-mainwp-ui.php +1364 -321 5.1 → 6.2.1 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' );
@@ -873,9 +998,9 @@
873 998 * @since 4.0
874 999 */
875 1000 do_action( 'mainwp_before_header', $websites );
876 1001 ?>
877 - <div id="mainwp-top-header" class="ui native sticky">
1002 + <div id="mainwp-top-header">
878 1003 <div class="ui grid">
879 1004 <div class="center aligned middle aligned column" style="width:72px!important;padding:0!important;">
880 1005 <a href="
881 1006 <?php
@@ -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,26 +1158,93 @@
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 - jQuery( '.ui.sticky' ).sticky( {
1034 - pushing: false,
1035 - } ).sticky();
1036 -
1037 1247 jQuery( '#mainwp-help-sidebar' ).on( 'click', function() {
1038 1248 jQuery( '.ui.help.sidebar' ).sidebar( {
1039 1249 transition: 'overlay'
1040 1250 } );
@@ -1051,11 +1261,51 @@
1051 1261 jQuery( '.ui.sites.sidebar' ).sidebar( 'toggle' );
1052 1262 return false;
1053 1263 } );
1054 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 } ?>
1055 1301 } );
1056 1302 </script>
1303 +
1304 + <?php static::render_help_modal(); ?>
1305 + <?php static::render_loader_element(); ?>
1057 1306 <?php
1307 + ob_start();
1058 1308 /**
1059 1309 * Action: mainwp_after_header
1060 1310 *
1061 1311 * Fires after the MainWP header element.
@@ -1064,8 +1314,19 @@
1064 1314 *
1065 1315 * @since 4.0
1066 1316 */
1067 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 + }
1068 1329 ?>
1069 1330 <?php
1070 1331 }
1071 1332
@@ -1265,19 +1526,53 @@
1265 1526 * @return mixed $output Render header action buttons html.
1266 1527 *
1267 1528 * @uses \MainWP\Dashboard\MainWP_DB::get_websites_count()
1268 1529 */
1269 - public static function render_header_actions() { //phpcs:ignore -- NOSONAR - complex method.
1530 + public static function render_header_actions() { // phpcs:ignore -- NOSONAR - complex method.
1270 1531 $sites_count = MainWP_DB::instance()->get_websites_count();
1271 1532 $sidebar_pages = array( 'ManageGroups', 'PostBulkManage', 'PostBulkAdd', 'PageBulkManage', 'PageBulkAdd', 'ThemesManage', 'ThemesInstall', 'ThemesAutoUpdate', 'PluginsManage', 'PluginsInstall', 'PluginsAutoUpdate', 'UserBulkManage', 'UserBulkAdd', 'UpdateAdminPasswords', 'Extensions' );
1272 1533 $sidebar_pages = apply_filters( 'mainwp_sidbar_pages', $sidebar_pages ); // deprecated filter.
1273 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 = '';
1274 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 +
1275 1570 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1276 - $page = isset( $_GET['page'] ) ? wp_unslash( $_GET['page'] ) : '';
1277 - ob_start();
1278 - if ( isset( $_GET['dashboard'] ) || isset( $_GET['id'] ) || isset( $_GET['updateid'] ) || isset( $_GET['emailsettingsid'] ) || isset( $_GET['scanid'] ) ) :
1279 - $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'] ) ) {
1280 1575 if ( isset( $_GET['dashboard'] ) ) {
1281 1576 $id = intval( $_GET['dashboard'] );
1282 1577 } elseif ( isset( $_GET['id'] ) ) {
1283 1578 $id = intval( $_GET['id'] );
@@ -1286,65 +1581,145 @@
1286 1581 } elseif ( isset( $_GET['emailsettingsid'] ) ) {
1287 1582 $id = intval( $_GET['emailsettingsid'] );
1288 1583 } elseif ( isset( $_GET['scanid'] ) ) {
1289 1584 $id = intval( $_GET['scanid'] );
1585 + } elseif ( isset( $_GET['monitor_wpid'] ) ) {
1586 + $id = intval( $_GET['monitor_wpid'] );
1290 1587 }
1291 -
1292 - $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 ) :
1293 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 + ?>
1294 1604 <?php if ( $id && $website && '' !== $website->sync_errors ) : ?>
1295 - <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>
1296 - <?php else : ?>
1297 - <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' ); ?>" >
1298 - <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>
1299 1632 </a>
1300 1633 <?php endif; ?>
1301 - <?php else : ?>
1302 - <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' ); ?>">
1303 - <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>
1304 1658 </a>
1305 1659 <?php endif; ?>
1306 1660
1307 - <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">
1308 - <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' ); ?>
1309 1663 <div class="menu">
1310 - <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>
1311 - <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>
1312 - <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>
1313 - <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>
1314 - <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>
1315 - <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>
1316 - <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>
1317 - <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>
1318 1674 </div>
1319 1675 </div>
1320 1676
1321 - <?php if ( ( 'mainwp_tab' === $page ) || isset( $_GET['dashboard'] ) || in_array( $page, $sidebar_pages ) ) : // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended ?>
1322 - <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' ); ?>">
1323 - <i class="cog icon"></i>
1324 - </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>
1325 1681 <?php endif; ?>
1326 - <?php
1327 - // phpcs:enable
1328 - /**
1329 - * Filter: mainwp_header_actions_right
1330 - *
1331 - * Filters the MainWP header element actions.
1332 - *
1333 - * @since 4.0
1334 - */
1335 - $actions = apply_filters( 'mainwp_header_actions_right', '' );
1336 - if ( ! empty( $actions ) ) {
1337 - echo $actions; // phpcs:ignore WordPress.Security.EscapeOutput
1338 - }
1339 - ?>
1340 - <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' ); ?>">
1341 - <i class="globe icon"></i>
1342 - </a>
1343 - <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' ); ?>">
1344 - <i class="palette icon"></i>
1345 - </div>
1346 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 +
1347 1722 <?php
1348 1723 /**
1349 1724 * After select theme actions.
1350 1725 *
@@ -1350,51 +1725,79 @@
1350 1725 *
1351 1726 * @since 4.5.2
1352 1727 */
1353 1728 do_action( 'mainwp_header_actions_after_select_themes' );
1729 + $show_avar = get_option( 'show_avatars' );
1354 1730 ?>
1355 - <div class="ui icon top left pointing dropdown button" id="mainwp-help-menu-icon-button">
1356 - <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 + ?>
1357 1750 <div class="menu">
1358 - <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' ); ?>">
1359 - <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' ); ?>
1360 1753 </a>
1361 - <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' ); ?>">
1362 - <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' ); ?>
1363 1756 </a>
1364 - <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' ); ?>">
1365 - <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' ); ?>
1366 1759 </a>
1367 - <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' ); ?>">
1368 - <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' ); ?>
1369 1762 </a>
1370 - <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' ); ?>">
1371 - <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' ); ?>
1372 1765 </a>
1373 - <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' ); ?>">
1374 - <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' ); ?>
1375 1769 </a>
1376 - <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. ?>
1377 - <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' ); ?>
1378 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>
1379 1787 </div>
1380 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 ); ?>">
1381 1794 <script>
1382 1795 jQuery( document ).ready( function( $ ) {
1383 - $( '#mainwp-help-menu-icon-button' ).dropdown();
1796 + $( '#mainwp-user-menu-button' ).dropdown();
1384 1797 } );
1385 1798 </script>
1386 -
1387 1799 <?php
1388 -
1389 - $all_updates = wp_get_update_data();
1390 - if ( is_array( $all_updates ) && isset( $all_updates['counts']['total'] ) && 0 < $all_updates['counts']['total'] ) {
1391 - ?>
1392 - <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">
1393 - <i class="exclamation triangle icon"></i>
1394 - </a>
1395 - <?php
1396 - }
1397 1800 return ob_get_clean();
1398 1801 }
1399 1802
1400 1803 /**
@@ -1401,9 +1804,9 @@
1401 1804 * Method render_page_navigation()
1402 1805 *
1403 1806 * Render page navigation.
1404 1807 *
1405 - * @param array $subitems [access, active, style].
1808 + * @param array $subitems [access, active, style, target, rel].
1406 1809 * @param null $name_caller Menu Name.
1407 1810 */
1408 1811 public static function render_page_navigation( $subitems = array(), $name_caller = null ) { //phpcs:ignore -- NOSONAR - complex.
1409 1812
@@ -1416,10 +1819,39 @@
1416 1819 */
1417 1820 $subitems = apply_filters( 'mainwp_page_navigation', $subitems, $name_caller );
1418 1821 ?>
1419 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 );
1420 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; ?>
1421 1852 <div class="ui vertical menu mainwp-page-navigation">
1853 +
1422 1854 <?php
1423 1855
1424 1856 if ( is_array( $subitems ) ) {
1425 1857 foreach ( $subitems as $item ) {
@@ -1445,11 +1877,22 @@
1445 1877 if ( isset( $item['style'] ) ) {
1446 1878 $style = $item['style'];
1447 1879 }
1448 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 +
1449 1893 ?>
1450 -
1451 - <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; ?>>
1452 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 ?>
1453 1896 </a>
1454 1897 <?php
1455 1898 }
@@ -1462,24 +1905,21 @@
1462 1905 </div>
1463 1906 <?php
1464 1907 $is_site = MainWP_System::is_mainwp_site_page();
1465 1908 if ( $is_site ) {
1466 - ?>
1467 - <div id="mainwp-site-mode-wrap">
1468 - <?php } ?>
1469 -
1470 - <?php
1909 + echo '<div id="mainwp-site-mode-wrap">';
1910 + }
1471 1911 }
1472 1912
1473 - /**
1474 - * Method render_header()
1475 - *
1476 - * Render page title.
1477 - *
1478 - * @param string $title Page title.
1479 - *
1480 - * @return void Render page title and hidden divider html.
1481 - */
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 + */
1482 1922 public static function render_header( $title = '' ) {
1483 1923 static::render_top_header( array( 'title' => $title ) );
1484 1924 echo '<div class="ui hidden clearing fitted divider"></div>';
1485 1925 echo '<div class="wrap">';
@@ -1558,14 +1998,40 @@
1558 1998 $page = MainWP_System_Utility::get_page_id( $screen_id );
1559 1999 if ( empty( $page ) ) {
1560 2000 return;
1561 2001 }
1562 - $wgsorted = get_user_option( 'mainwp_widgets_sorted_' . strtolower( $page ) );
1563 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 +
1564 2026 if ( ! empty( $wgsorted ) && is_string( $wgsorted ) ) {
1565 2027 $wgsorted = json_decode( $wgsorted, true );
1566 2028 }
1567 2029
2030 + if ( ! is_array( $wgsorted ) ) {
2031 + $wgsorted = array();
2032 + }
2033 +
1568 2034 $client_id = 0;
1569 2035 if ( 'mainwp_page_manageclients' === $page ) {
1570 2036 $sorted_array = is_array( $wgsorted ) ? $wgsorted : array();
1571 2037 $wgsorted = array();
@@ -1576,12 +2042,8 @@
1576 2042 }
1577 2043
1578 2044 $wgsorted = apply_filters( 'mainwp_do_widget_boxes_sorted', $wgsorted, $page, $client_id );
1579 2045
1580 - if ( ! is_array( $wgsorted ) ) {
1581 - $wgsorted = array();
1582 - }
1583 -
1584 2046 if ( 'mainwp_page_manageclients' === $page ) {
1585 2047 $show_widgets = get_user_option( 'mainwp_clients_show_widgets' );
1586 2048 } elseif ( 'toplevel_page_mainwp_tab' === $page || 'mainwp_page_managesites' === $page ) {
1587 2049 $show_widgets = get_user_option( 'mainwp_settings_show_widgets' );
@@ -1592,8 +2054,17 @@
1592 2054 if ( ! is_array( $show_widgets ) ) {
1593 2055 $show_widgets = array();
1594 2056 }
1595 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
1596 2067 if ( isset( $mainwp_widget_boxes[ $page ] ) ) {
1597 2068 foreach ( (array) $mainwp_widget_boxes[ $page ] as $box ) {
1598 2069 if ( false === $box || ! isset( $box['callback'] ) ) {
1599 2070 continue;
@@ -1606,105 +2077,153 @@
1606 2077
1607 2078 $layout = array();
1608 2079 if ( isset( $wgsorted[ $box['id'] ] ) ) {
1609 2080 $val = $wgsorted[ $box['id'] ];
1610 - if ( is_array( $val ) && isset( $val['col'] ) ) {
2081 + if ( is_array( $val ) && ( isset( $val['x'] ) || isset( $val['w'] ) ) ) {
1611 2082 $layout = array(
1612 - 'col' => $val['col'],
1613 - 'row' => $val['row'],
1614 - 'size_x' => $val['size_x'],
1615 - 'size_y' => $val['size_y'],
2083 + 'x' => $val['x'],
2084 + 'y' => $val['y'],
2085 + 'w' => $val['w'],
2086 + 'h' => $val['h'],
1616 2087 );
1617 2088 }
1618 2089 }
1619 - 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'] ) ) {
1620 2093 $layout = array(
1621 - 'col' => $box['layout'][0],
1622 - 'row' => $box['layout'][1],
1623 - 'size_x' => $box['layout'][2],
1624 - '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'],
1625 2098 );
1626 2099 }
1627 - $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'] ) : '' ) . '" ';
1628 - echo '<div id="widget-' . esc_html( $box['id'] ) . '" class="ui segment mainwp-widget" ' . $layout_attrs_escaped . '>' . "\n"; //phpcs:ignore -- escaped.
1629 - call_user_func( $box['callback'], $screen_id, $args );
1630 - 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";
1631 2119 echo "</div>\n";
1632 2120
1633 2121 }
1634 2122 }
1635 - $breakpoint = apply_filters( 'mainwp_flexible_widgets_breakpoint', 1367 );
1636 2123 ?>
2124 + </div>
1637 2125 <script type="text/javascript">
1638 - let is_mobile = false;
1639 - if( jQuery( window ).width() < <?php echo intval( $breakpoint ); ?> ) {
1640 - is_mobile = true;
1641 - }
1642 - console.log('mobile: ' + is_mobile);
1643 -
1644 - if ( ! is_mobile ) {
1645 2126 let page_sortablewidgets = '<?php echo esc_js( $page ); ?>';
2127 + let page_widget = '<?php echo esc_js( $page_widget ); ?>';
1646 2128 jQuery( document ).ready( function( $ ) {
1647 - let wgIds = [];
1648 - jQuery( ".mainwp-widget" ).each( function () {
1649 - wgIds.push( jQuery( this ).attr('id') );
1650 - } );
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);
1651 2149
1652 - let $mainwp_gridster = jQuery( '.gridster' ).gridster( {
1653 - auto_init: true,
1654 - autogenerate_stylesheet: true,
1655 - shift_larger_widgets_down: false,
1656 - shift_widgets_up: true,
1657 - widget_selector: "div.mainwp-widget",
1658 - widget_margins: [20, 20],
1659 - widget_base_dimensions: ["auto", 20],
1660 - min_cols: 1,
1661 - max_cols: 12,
1662 - max_size_x: 12,
1663 - max_rows: 500,
1664 - avoid_overlapped_widgets: true,
1665 - collision: {
1666 - wait_for_mouseup: true
1667 - },
1668 - draggable: {
1669 - handle: '.handle-drag',
1670 - stop: function (e, ui, $widget) {
1671 - mainwp_overview_gridster_reorder(this);
1672 - }
1673 - },
1674 - resize: {
1675 - enabled: true,
1676 - handle_append_to: ".mainwp-resize-handle",
1677 - stop: function (e, ui, $widget) {
1678 - mainwp_overview_gridster_reorder(this);
1679 - }
1680 - }
1681 - } ).data('gridster');
2150 + grid.on('change', function() {
2151 + mainwp_overview_gridstack_save_layout(<?php echo (int) $client_id; ?>, grid);
2152 + });
1682 2153
1683 - mainwp_overview_gridster_reorder = function( $gridObj ){
1684 - let orders = $gridObj.serialize();
1685 - let postVars = {
1686 - action:'mainwp_widgets_order',
1687 - page: page_sortablewidgets,
1688 - order:JSON.stringify(orders),
1689 - wgids: JSON.stringify(wgIds),
1690 - item_id: <?php echo intval( $client_id ); ?>
1691 - };
1692 - jQuery.post( ajaxurl, mainwp_secure_data( postVars ), function ( res ) {
1693 - } );
1694 - }
1695 - });
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 + }
1696 2157
1697 - }
2158 + jQuery('#mainwp-widgets-placeholder').dimmer('hide');
2159 + });
1698 2160 </script>
1699 - <?php
2161 + <?php
1700 2162 }
1701 2163
1702 - /**
1703 - * Method render_empty_bulk_actions()
1704 - *
1705 - * Render empty bulk actions when drop down is disabled.
1706 - */
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 + */
1707 2226 public static function render_empty_bulk_actions() {
1708 2227 ?>
1709 2228 <select class="ui disabled dropdown" id="mainwp-bulk-actions">
1710 2229 <option value=""><?php esc_html_e( 'Bulk Actions', 'mainwp' ); ?></option>
@@ -1722,9 +2241,9 @@
1722 2241 */
1723 2242 public static function render_modal_install_plugin_theme( $what = 'plugin' ) {
1724 2243 ?>
1725 2244 <div id="plugintheme-installation-progress-modal" class="ui modal">
1726 - <i class="close icon"></i>
2245 + <i class="close icon"></i>
1727 2246 <div class="header">
1728 2247 <?php
1729 2248 if ( 'plugin' === $what ) {
1730 2249 esc_html_e( 'Plugin Installation', 'mainwp' );
@@ -1770,9 +2289,9 @@
1770 2289 * @since 4.1
1771 2290 */
1772 2291 do_action( 'mainwp_install_plugin_theme_modal_action', $what );
1773 2292 ?>
1774 - <div class="ui cancel button"><?php esc_html_e( 'Close', 'mainwp' ); ?></div>
2293 +
1775 2294 </div>
1776 2295 </div>
1777 2296 <?php
1778 2297 }
@@ -1793,9 +2312,9 @@
1793 2312 ?>
1794 2313 </div>
1795 2314 <div class="content" id="mainwp-upload-custom-icon-content">
1796 2315 <form action="" method="post" enctype="multipart/form-data" name="uploadicon_form" id="uploadicon_form" class="">
1797 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
2316 + <?php self::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1798 2317 <div class="ui message" id="mainwp-message-zone-upload" style="display:none;"></div>
1799 2318 <?php
1800 2319 /**
1801 2320 * Action: mainwp_after_upload_custom_icon
@@ -1844,18 +2363,18 @@
1844 2363 </div>
1845 2364 <?php
1846 2365 }
1847 2366
1848 - /**
1849 - * Method render_show_all_updates_button()
1850 - *
1851 - * Render show all updates button.
1852 - *
1853 - * @return void Render Show All Updates button html.
1854 - */
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 + */
1855 2374 public static function render_show_all_updates_button() {
1856 2375 ?>
1857 - <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">
1858 2377 <?php
1859 2378 /**
1860 2379 * Filter: mainwp_show_all_updates_button_text
1861 2380 *
@@ -1881,20 +2400,21 @@
1881 2400 <i class="sort icon"></i><i class="sort up icon"></i><i class="sort down icon"></i>
1882 2401 <?php
1883 2402 }
1884 2403
1885 - /**
1886 - * Method render_modal_edit_notes()
1887 - *
1888 - * Render modal window for edit notes.
1889 - *
1890 - * @param string $what What modal window to render. Default = site.
1891 - *
1892 - * @return void
1893 - */
2404 + /**
2405 + * Method render_modal_edit_notes()
2406 + *
2407 + * Render modal window for edit notes.
2408 + *
2409 + * @param string $what What modal window to render. Default = site.
2410 + *
2411 + * @return void
2412 + */
1894 2413 public static function render_modal_edit_notes( $what = 'site' ) {
1895 2414 ?>
1896 2415 <div id="mainwp-notes-modal" class="ui modal">
2416 + <i class="close icon" id="mainwp-notes-cancel"></i>
1897 2417 <div class="header"><?php esc_html_e( 'Notes', 'mainwp' ); ?></div>
1898 2418 <div class="content" id="mainwp-notes-content">
1899 2419 <div id="mainwp-notes-status" class="ui message hidden"></div>
1900 2420 <?php
@@ -1932,9 +2452,8 @@
1932 2452 <input type="button" class="ui green button" id="mainwp-notes-save" value="<?php esc_attr_e( 'Save Note', 'mainwp' ); ?>" style="display:none;"/>
1933 2453 <input type="button" class="ui green button" id="mainwp-notes-edit" value="<?php esc_attr_e( 'Edit Note', 'mainwp' ); ?>"/>
1934 2454 </div>
1935 2455 <div class="eight wide column">
1936 - <input type="button" class="ui button" id="mainwp-notes-cancel" value="<?php esc_attr_e( 'Close', 'mainwp' ); ?>"/>
1937 2456 <input type="hidden" id="mainwp-notes-websiteid" value=""/>
1938 2457 <input type="hidden" id="mainwp-notes-slug" value=""/>
1939 2458 <input type="hidden" id="mainwp-which-note" value="<?php echo esc_html( $what ); ?>"/>
1940 2459 <input type="hidden" id="mainwp-notes-itemid" value=""/>
@@ -1941,10 +2460,9 @@
1941 2460 </div>
1942 2461 </div>
1943 2462 </div>
1944 2463 </div>
1945 -
1946 - <?php
2464 + <?php
1947 2465 }
1948 2466
1949 2467 /**
1950 2468 * No Sites Modal
@@ -1964,14 +2482,14 @@
1964 2482 <div class="ui hidden divider"></div>
1965 2483 <div class="ui hidden divider"></div>
1966 2484 <a href="admin.php?page=managesites&do=new" class="ui big green button"><?php esc_html_e( 'Connect Your WordPress Site', 'mainwp' ); ?></a>
1967 2485 <div class="ui hidden fitted divider"></div>
1968 - <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>
1969 2487 </div>
1970 2488 <div class="actions">
1971 2489 <div class="ui grid">
1972 2490 <div class="eight wide left aligned middle aligned column">
1973 - <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>
1974 2492 </div>
1975 2493 <div class="eight wide column">
1976 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' ); ?>"/>
1977 2495 </div>
@@ -1989,13 +2507,411 @@
1989 2507 endif;
1990 2508 }
1991 2509
1992 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 + /**
1993 2909 * Method render_screen_options()
1994 2910 *
1995 2911 * Render modal window for Page Settings.
1996 2912 *
1997 - * @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.
1998 2914 *
1999 2915 * @return void Render modal window for Page Settings html.
2000 2916 */
2001 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.
@@ -2000,29 +2916,36 @@
2000 2916 */
2001 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.
2002 2918
2003 2919 $default_widgets = array(
2004 - 'overview' => esc_html__( 'Updates Overview', 'mainwp' ),
2005 - 'recent_posts' => esc_html__( 'Recent Posts', 'mainwp' ),
2006 - 'recent_pages' => esc_html__( 'Recent Pages', 'mainwp' ),
2007 - 'plugins' => esc_html__( 'Plugins (Individual Site Overview page)', 'mainwp' ),
2008 - 'themes' => esc_html__( 'Themes (Individual Site Overview page)', 'mainwp' ),
2009 - 'connection_status' => esc_html__( 'Connection Status', 'mainwp' ),
2010 - 'security_issues' => esc_html__( 'Security Issues', 'mainwp' ),
2011 - 'notes' => esc_html__( 'Notes (Individual Site Overview page)', 'mainwp' ),
2012 - 'clients' => esc_html__( 'Clients', 'mainwp' ),
2013 - 'child_site_info' => esc_html__( 'Child site info (Individual Site Overview page)', 'mainwp' ),
2014 - 'client_info' => esc_html__( 'Client info (Individual Site Overview page)', 'mainwp' ),
2015 - 'non_mainwp_changes' => esc_html__( 'Non-MainWP Changes', 'mainwp' ),
2016 - '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' ),
2017 2935 );
2018 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 +
2019 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.
2020 2943
2021 2944 /**
2022 2945 * Filter: mainwp_widgets_screen_options
2023 2946 *
2024 - * 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.
2025 2948 *
2026 2949 * @since 4.0
2027 2950 */
2028 2951 $custom_opts = apply_filters( 'mainwp_widgets_screen_options', $custom_opts );
@@ -2104,9 +3027,9 @@
2104 3027 }
2105 3028 esc_html_e( 'Show widgets', 'mainwp' );
2106 3029 ?>
2107 3030 </label>
2108 - <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">
2109 3032 <ul class="mainwp_hide_wpmenu_checkboxes">
2110 3033 <?php
2111 3034 foreach ( $default_widgets as $name => $title ) {
2112 3035 $_selected = '';
@@ -2128,8 +3051,9 @@
2128 3051 </div>
2129 3052 </div>
2130 3053 <?php
2131 3054 endif;
3055 + // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized.Recommended
2132 3056 ?>
2133 3057 <input type="hidden" name="reset_overview_which_settings" value="<?php echo esc_html( $which_settings ); ?>" />
2134 3058 <?php
2135 3059 /**
@@ -2155,12 +3079,12 @@
2155 3079 <i class="close icon"></i>
2156 3080 <div class="header"><?php esc_html_e( 'Select MainWP Theme', 'mainwp' ); ?></div>
2157 3081 <div class="content ui form">
2158 3082 <div class="ui blue message">
2159 - <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>
2160 3084 </div>
2161 3085 <form method="POST" action="" name="mainwp_select_mainwp_themes_form" id="mainwp_select_mainwp_themes_form">
2162 - <?php wp_nonce_field( 'mainwp-admin-nonce' ); ?>
3086 + <?php self::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
2163 3087 <input type="hidden" name="wp_scr_options_nonce" value="<?php echo esc_attr( wp_create_nonce( 'MainWPSelectThemes' ) ); ?>" />
2164 3088 <?php
2165 3089 /**
2166 3090 * Action: mainwp_select_themes_modal_top
@@ -2205,15 +3129,15 @@
2205 3129 $mainwp_api_key = MainWP_Api_Manager_Key::instance()->get_decrypt_master_api_key();
2206 3130 ?>
2207 3131 <div class="ui small modal" id="mainwp-install-extensions-promo-modal">
2208 3132 <i class="close icon"></i>
2209 - <?php if ( empty( $mainwp_api_key ) ) : ?>
3133 + <?php if ( empty( $mainwp_api_key ) ) : ?>
2210 3134 <div class="header"><?php esc_html_e( 'Get MainWP Pro', 'mainwp' ); ?></div>
2211 3135 <div class="content">
2212 3136 <div class="ui header"><?php esc_html_e( 'With your MainWP Pro subscription, you get access to:', 'mainwp' ); ?></div>
2213 3137 <div class="ui bulleted list">
2214 - <div class="item"><?php esc_html_e( 'All 30+ Existing Premium Extensions', 'mainwp' ); ?></div>
2215 - <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>
2216 3140 <div class="item"><?php esc_html_e( 'Critical Security & Performance Updates', 'mainwp' ); ?></div>
2217 3141 <div class="item"><?php esc_html_e( 'Priority Support with Subscription', 'mainwp' ); ?></div>
2218 3142 <div class="item"><?php esc_html_e( 'Manage Unlimited Websites', 'mainwp' ); ?></div>
2219 3143 </div>
@@ -2219,49 +3143,100 @@
2219 3143 </div>
2220 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. ?>
2221 3145 </div>
2222 3146 <?php else : ?>
2223 - <div class="header"><?php esc_html_e( 'Install Extensions', 'mainwp' ); ?></div>
3147 + <div class="header"><?php esc_html_e( 'Install Add-ons', 'mainwp' ); ?></div>
2224 3148 <div class="content">
2225 - <div class="ui header"><?php esc_html_e( 'Extension not activated', 'mainwp' ); ?></div>
2226 - <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>
2227 3151 </div>
2228 3152 <?php endif; ?>
2229 3153 </div>
2230 - <?php
3154 + <?php
2231 3155 }
2232 3156
2233 - /**
2234 - * Method render_empty_element_placeholder()
2235 - *
2236 - * Renders the content for empty elements.
2237 - *
2238 - * @param string $placeholder Placelolder text.
2239 - */
2240 - 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 = '' ) {
2241 3167 ?>
2242 - <div class="ui one column grid">
2243 - <div class="middle aligned center aligned column">
2244 - <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"/>
2245 - <?php if ( '' !== $placeholder ) : ?>
2246 - <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. ?>
2247 3172 <?php else : ?>
2248 - <p><?php echo esc_html__( 'Nothing to show here, check back later!', 'mainwp' ); ?></p>
3173 + <i class="search icon"></i>
2249 3174 <?php endif; ?>
2250 - </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>
2251 3188 </div>
2252 - <?php
3189 + <?php
2253 3190 }
2254 3191
2255 - /**
2256 - * Method render_modal_save_segment()
2257 - *
2258 - * Render modal window.
2259 - *
2260 - * @return void
2261 - */
2262 - 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 = '' ) {
2263 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 + ?>
2264 3239 <div id="mainwp-common-filter-segment-modal" class="ui tiny modal">
2265 3240 <i class="close icon" id="mainwp-common-filter-segment-cancel"></i>
2266 3241 <div class="header"><?php esc_html_e( 'Save Segment', 'mainwp' ); ?></div>
2267 3242 <div class="content" id="mainwp-common-filter-segment-content">
@@ -2294,13 +3269,81 @@
2294 3269
2295 3270 </div>
2296 3271 </div>
2297 3272 </div>
3273 + <input type="hidden" id="mainwp-common-filter-segments-model-name" value="<?php echo esc_attr( $name ); ?>" />
2298 3274 </div>
3275 + <?php
3276 + }
2299 3277
2300 - <?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;
2301 3302 }
2302 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 + }
2303 3346
2304 3347 /**
2305 3348 * Method get_default_icons().
2306 3349 *