| @@ -178,9 +178,9 @@ | ||
| 178 | 178 | |
| 179 | 179 | $sites = get_sites(); |
| 180 | 180 | |
| 181 | 181 | foreach ( $sites as $s ) { |
| 182 | - switch_to_blog( $s->blog_id ); | |
| 182 | + switch_to_blog( (int) $s->blog_id ); | |
| 183 | 183 | $active_plugins = get_option( 'active_plugins' ); |
| 184 | 184 | |
| 185 | 185 | /* |
| 186 | 186 | * If this plugin was activated in the subsite individually |
| @@ -284,17 +284,10 @@ | ||
| 284 | 284 | $icon = ( new Logo() )->get_base64_logo(); |
| 285 | 285 | add_menu_page( 'Jetpack', 'Jetpack', 'jetpack_network_admin_page', 'jetpack', array( $this, 'wrap_network_admin_page' ), $icon, 3 ); |
| 286 | 286 | $jetpack_sites_page_hook = add_submenu_page( 'jetpack', __( 'Jetpack Sites', 'jetpack' ), __( 'Sites', 'jetpack' ), 'jetpack_network_sites_page', 'jetpack', array( $this, 'wrap_network_admin_page' ) ); |
| 287 | 287 | $jetpack_settings_page_hook = add_submenu_page( 'jetpack', __( 'Settings', 'jetpack' ), __( 'Settings', 'jetpack' ), 'jetpack_network_settings_page', 'jetpack-settings', array( $this, 'wrap_render_network_admin_settings_page' ) ); |
| 288 | - add_action( "admin_print_styles-$jetpack_sites_page_hook", array( 'Jetpack_Admin_Page', 'load_wrapper_styles' ) ); | |
| 289 | - add_action( "admin_print_styles-$jetpack_settings_page_hook", array( 'Jetpack_Admin_Page', 'load_wrapper_styles' ) ); | |
| 290 | - /** | |
| 291 | - * As jetpack_register_genericons is by default fired off a hook, | |
| 292 | - * the hook may have already fired by this point. | |
| 293 | - * So, let's just trigger it manually. | |
| 294 | - */ | |
| 295 | - require_once JETPACK__PLUGIN_DIR . '_inc/genericons.php'; | |
| 296 | - jetpack_register_genericons(); | |
| 288 | + add_action( "load-$jetpack_sites_page_hook", array( $this, 'admin_init_network_page' ) ); | |
| 289 | + add_action( "load-$jetpack_settings_page_hook", array( $this, 'admin_init_network_page' ) ); | |
| 297 | 290 | } |
| 298 | 291 | |
| 299 | 292 | /** |
| 300 | 293 | * Provides functionality for the Jetpack > Sites page. |
| @@ -332,9 +325,9 @@ | ||
| 332 | 325 | $url = add_query_arg( 'action', 'connected', $url ); |
| 333 | 326 | } |
| 334 | 327 | |
| 335 | 328 | wp_safe_redirect( $url ); |
| 336 | - exit; | |
| 329 | + exit( 0 ); | |
| 337 | 330 | |
| 338 | 331 | case 'subsitedisconnect': |
| 339 | 332 | check_admin_referer( 'jetpack-subsite-disconnect' ); |
| 340 | 333 | Jetpack::log( 'subsitedisconnect' ); |
| @@ -386,10 +379,10 @@ | ||
| 386 | 379 | $notice = __( 'Site connection failed!', 'jetpack' ); |
| 387 | 380 | $classname = 'error'; |
| 388 | 381 | } |
| 389 | 382 | ?> |
| 390 | - <div id="message" class="<?php echo esc_attr( $classname ); ?> jetpack-message jp-connect" style="display:block !important;"> | |
| 391 | - <p><?php echo esc_html( $notice ); ?></p> | |
| 383 | + <div id="message" class="<?php echo esc_attr( $classname ?? '' ); ?> jetpack-message jp-connect" style="display:block !important;"> | |
| 384 | + <p><?php echo esc_html( $notice ?? '' ); ?></p> | |
| 392 | 385 | </div> |
| 393 | 386 | <?php |
| 394 | 387 | } |
| 395 | 388 | |
| @@ -482,9 +475,9 @@ | ||
| 482 | 475 | $blog_details = get_blog_details(); |
| 483 | 476 | |
| 484 | 477 | $network = get_network(); |
| 485 | 478 | |
| 486 | - switch_to_blog( $network->blog_id ); | |
| 479 | + switch_to_blog( (int) $network->blog_id ); | |
| 487 | 480 | // The blog id on WordPress.com of the primary network site. |
| 488 | 481 | $network_wpcom_blog_id = Jetpack_Options::get_option( 'id' ); |
| 489 | 482 | restore_current_blog(); |
| 490 | 483 | |
| @@ -512,12 +505,75 @@ | ||
| 512 | 505 | ); |
| 513 | 506 | } |
| 514 | 507 | |
| 515 | 508 | /** |
| 516 | - * A hook handler for adding admin pages and subpages. | |
| 509 | + * Initializes assets for network admin pages. | |
| 510 | + * | |
| 511 | + * @since 15.7 | |
| 517 | 512 | */ |
| 513 | + public function admin_init_network_page() { | |
| 514 | + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_network_admin_scripts' ) ); | |
| 515 | + | |
| 516 | + // Match the modernized single-site dashboards (e.g. Jetpack Forms): the | |
| 517 | + // network Sites/Settings pages render as full-viewport AdminPage shells, | |
| 518 | + // so strip core admin notices that would otherwise break the pinned | |
| 519 | + // layout. Network Admin fires `network_admin_notices`/`all_admin_notices` | |
| 520 | + // (not `admin_notices`). Jetpack's own notices use the `jetpack_notices` | |
| 521 | + // hook and are unaffected. | |
| 522 | + remove_all_actions( 'network_admin_notices' ); | |
| 523 | + remove_all_actions( 'all_admin_notices' ); | |
| 524 | + } | |
| 525 | + | |
| 526 | + /** | |
| 527 | + * Enqueues the JS and CSS for the unified network admin header. | |
| 528 | + * | |
| 529 | + * @since 15.7 | |
| 530 | + */ | |
| 531 | + public function enqueue_network_admin_scripts() { | |
| 532 | + $build_dir = JETPACK__PLUGIN_DIR . '_inc/build/'; | |
| 533 | + $script_asset_path = $build_dir . 'network-admin.asset.php'; | |
| 534 | + | |
| 535 | + if ( ! file_exists( $script_asset_path ) ) { | |
| 536 | + return; | |
| 537 | + } | |
| 538 | + | |
| 539 | + $script_asset = require $script_asset_path; | |
| 540 | + | |
| 541 | + wp_enqueue_script( | |
| 542 | + 'jetpack-network-admin', | |
| 543 | + plugins_url( '_inc/build/network-admin.js', JETPACK__PLUGIN_FILE ), | |
| 544 | + $script_asset['dependencies'], | |
| 545 | + $script_asset['version'], | |
| 546 | + true | |
| 547 | + ); | |
| 548 | + | |
| 549 | + wp_enqueue_style( | |
| 550 | + 'jetpack-network-admin', | |
| 551 | + plugins_url( '_inc/build/network-admin.css', JETPACK__PLUGIN_FILE ), | |
| 552 | + array(), | |
| 553 | + $script_asset['version'] | |
| 554 | + ); | |
| 555 | + | |
| 556 | + wp_set_script_translations( 'jetpack-network-admin', 'jetpack' ); | |
| 557 | + | |
| 558 | + wp_localize_script( | |
| 559 | + 'jetpack-network-admin', | |
| 560 | + 'JetpackNetworkAdminData', | |
| 561 | + array( | |
| 562 | + 'sitesUrl' => network_admin_url( 'admin.php?page=jetpack' ), | |
| 563 | + 'settingsUrl' => network_admin_url( 'admin.php?page=jetpack-settings' ), | |
| 564 | + ) | |
| 565 | + ); | |
| 566 | + } | |
| 567 | + | |
| 568 | + /** | |
| 569 | + * Renders the Network Sites page with the unified admin header. | |
| 570 | + */ | |
| 518 | 571 | public function wrap_network_admin_page() { |
| 519 | - Jetpack_Admin_Page::wrap_ui( array( $this, 'network_admin_page' ) ); | |
| 572 | + echo '<div id="jp-network-admin-root" data-page="sites"></div>'; | |
| 573 | + echo '<div id="jp-network-admin-content" style="display:none">'; | |
| 574 | + $this->network_admin_page(); | |
| 575 | + echo '</div>'; | |
| 520 | 576 | } |
| 521 | 577 | |
| 522 | 578 | /** |
| 523 | 579 | * Handles the displaying of all sites on the network that are |
| @@ -527,9 +583,8 @@ | ||
| 527 | 583 | * @see Jetpack_Network::jetpack_sites_list() |
| 528 | 584 | */ |
| 529 | 585 | public function network_admin_page() { |
| 530 | 586 | global $current_site; |
| 531 | - $this->network_admin_page_header(); | |
| 532 | 587 | |
| 533 | 588 | $jp = Jetpack::init(); |
| 534 | 589 | |
| 535 | 590 | // We should be, but ensure we are on the main blog. |
| @@ -581,8 +636,9 @@ | ||
| 581 | 636 | /** |
| 582 | 637 | * Fires when the Jetpack > Settings page is saved. |
| 583 | 638 | * |
| 584 | 639 | * @since 2.9 |
| 640 | + * @return never | |
| 585 | 641 | */ |
| 586 | 642 | public function save_network_settings_page() { |
| 587 | 643 | |
| 588 | 644 | if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'jetpack-network-settings' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| @@ -592,9 +648,9 @@ | ||
| 592 | 648 | array( 'page' => 'jetpack-settings' ), |
| 593 | 649 | network_admin_url( 'admin.php' ) |
| 594 | 650 | ) |
| 595 | 651 | ); |
| 596 | - exit(); | |
| 652 | + exit( 0 ); | |
| 597 | 653 | } |
| 598 | 654 | |
| 599 | 655 | // Try to save the Protect allow list before anything else, since that action can result in errors. |
| 600 | 656 | $allow_list = isset( $_POST['global-allow-list'] ) ? filter_var( wp_unslash( $_POST['global-allow-list'] ) ) : ''; |
| @@ -610,9 +666,9 @@ | ||
| 610 | 666 | ), |
| 611 | 667 | network_admin_url( 'admin.php' ) |
| 612 | 668 | ) |
| 613 | 669 | ); |
| 614 | - exit(); | |
| 670 | + exit( 0 ); | |
| 615 | 671 | } |
| 616 | 672 | |
| 617 | 673 | /* |
| 618 | 674 | * Fields |
| @@ -644,16 +700,19 @@ | ||
| 644 | 700 | ), |
| 645 | 701 | network_admin_url( 'admin.php' ) |
| 646 | 702 | ) |
| 647 | 703 | ); |
| 648 | - exit(); | |
| 704 | + exit( 0 ); | |
| 649 | 705 | } |
| 650 | 706 | |
| 651 | 707 | /** |
| 652 | - * A hook handler for adding admin pages and subpages. | |
| 708 | + * Renders the Network Settings page with the unified admin header. | |
| 653 | 709 | */ |
| 654 | 710 | public function wrap_render_network_admin_settings_page() { |
| 655 | - Jetpack_Admin_Page::wrap_ui( array( $this, 'render_network_admin_settings_page' ) ); | |
| 711 | + echo '<div id="jp-network-admin-root" data-page="settings"></div>'; | |
| 712 | + echo '<div id="jp-network-admin-content" style="display:none">'; | |
| 713 | + $this->render_network_admin_settings_page(); | |
| 714 | + echo '</div>'; | |
| 656 | 715 | } |
| 657 | 716 | |
| 658 | 717 | /** |
| 659 | 718 | * A hook rendering the admin settings page. |
| @@ -658,9 +717,8 @@ | ||
| 658 | 717 | /** |
| 659 | 718 | * A hook rendering the admin settings page. |
| 660 | 719 | */ |
| 661 | 720 | public function render_network_admin_settings_page() { |
| 662 | - $this->network_admin_page_header(); | |
| 663 | 721 | $options = wp_parse_args( get_site_option( $this->settings_name ), $this->setting_defaults ); |
| 664 | 722 | |
| 665 | 723 | $modules = array(); |
| 666 | 724 | $module_slugs = Jetpack::get_available_modules(); |