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