| @@ -4,8 +4,9 @@ | ||
| 4 | 4 | * |
| 5 | 5 | * @package automattic/jetpack |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +use Automattic\Jetpack\Assets\Logo; | |
| 8 | 9 | use Automattic\Jetpack\Connection\Manager; |
| 9 | 10 | use Automattic\Jetpack\Connection\Tokens; |
| 10 | 11 | use Automattic\Jetpack\Status; |
| 11 | 12 | use Automattic\Jetpack\Waf\Brute_Force_Protection\Brute_Force_Protection_Shared_Functions; |
| @@ -177,9 +178,9 @@ | ||
| 177 | 178 | |
| 178 | 179 | $sites = get_sites(); |
| 179 | 180 | |
| 180 | 181 | foreach ( $sites as $s ) { |
| 181 | - switch_to_blog( $s->blog_id ); | |
| 182 | + switch_to_blog( (int) $s->blog_id ); | |
| 182 | 183 | $active_plugins = get_option( 'active_plugins' ); |
| 183 | 184 | |
| 184 | 185 | /* |
| 185 | 186 | * If this plugin was activated in the subsite individually |
| @@ -279,38 +280,23 @@ | ||
| 279 | 280 | * |
| 280 | 281 | * @since 2.9 |
| 281 | 282 | */ |
| 282 | 283 | public function add_network_admin_menu() { |
| 283 | - add_menu_page( 'Jetpack', 'Jetpack', 'jetpack_network_admin_page', 'jetpack', array( $this, 'wrap_network_admin_page' ), 'div', 3 ); | |
| 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 | + } | |
| 291 | + add_menu_page( 'Jetpack', 'Jetpack', 'jetpack_network_admin_page', 'jetpack', array( $this, 'wrap_network_admin_page' ), $icon, 3 ); | |
| 284 | 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' ) ); |
| 285 | 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' ) ); |
| 286 | - add_action( "admin_print_styles-$jetpack_sites_page_hook", array( 'Jetpack_Admin_Page', 'load_wrapper_styles' ) ); | |
| 287 | - add_action( "admin_print_styles-$jetpack_settings_page_hook", array( 'Jetpack_Admin_Page', 'load_wrapper_styles' ) ); | |
| 288 | - /** | |
| 289 | - * As jetpack_register_genericons is by default fired off a hook, | |
| 290 | - * the hook may have already fired by this point. | |
| 291 | - * So, let's just trigger it manually. | |
| 292 | - */ | |
| 293 | - require_once JETPACK__PLUGIN_DIR . '_inc/genericons.php'; | |
| 294 | - jetpack_register_genericons(); | |
| 295 | - | |
| 296 | - if ( ! wp_style_is( 'jetpack-icons', 'registered' ) ) { | |
| 297 | - wp_register_style( 'jetpack-icons', plugins_url( 'css/jetpack-icons.min.css', JETPACK__PLUGIN_FILE ), false, JETPACK__VERSION ); | |
| 298 | - } | |
| 299 | - | |
| 300 | - add_action( 'admin_enqueue_scripts', array( $this, 'admin_menu_css' ) ); | |
| 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' ) ); | |
| 301 | 296 | } |
| 302 | 297 | |
| 303 | 298 | /** |
| 304 | - * Adds JP menu icon | |
| 305 | - * | |
| 306 | - * @since 2.9 | |
| 307 | - **/ | |
| 308 | - public function admin_menu_css() { | |
| 309 | - wp_enqueue_style( 'jetpack-icons' ); | |
| 310 | - } | |
| 311 | - | |
| 312 | - /** | |
| 313 | 299 | * Provides functionality for the Jetpack > Sites page. |
| 314 | 300 | * Does not do the display! |
| 315 | 301 | * |
| 316 | 302 | * @since 2.9 |
| @@ -345,9 +331,9 @@ | ||
| 345 | 331 | $url = add_query_arg( 'action', 'connected', $url ); |
| 346 | 332 | } |
| 347 | 333 | |
| 348 | 334 | wp_safe_redirect( $url ); |
| 349 | - exit; | |
| 335 | + exit( 0 ); | |
| 350 | 336 | |
| 351 | 337 | case 'subsitedisconnect': |
| 352 | 338 | check_admin_referer( 'jetpack-subsite-disconnect' ); |
| 353 | 339 | Jetpack::log( 'subsitedisconnect' ); |
| @@ -399,10 +385,10 @@ | ||
| 399 | 385 | $notice = __( 'Site connection failed!', 'jetpack' ); |
| 400 | 386 | $classname = 'error'; |
| 401 | 387 | } |
| 402 | 388 | ?> |
| 403 | - <div id="message" class="<?php echo esc_attr( $classname ); ?> jetpack-message jp-connect" style="display:block !important;"> | |
| 404 | - <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> | |
| 405 | 391 | </div> |
| 406 | 392 | <?php |
| 407 | 393 | } |
| 408 | 394 | |
| @@ -495,9 +481,9 @@ | ||
| 495 | 481 | $blog_details = get_blog_details(); |
| 496 | 482 | |
| 497 | 483 | $network = get_network(); |
| 498 | 484 | |
| 499 | - switch_to_blog( $network->blog_id ); | |
| 485 | + switch_to_blog( (int) $network->blog_id ); | |
| 500 | 486 | // The blog id on WordPress.com of the primary network site. |
| 501 | 487 | $network_wpcom_blog_id = Jetpack_Options::get_option( 'id' ); |
| 502 | 488 | restore_current_blog(); |
| 503 | 489 | |
| @@ -525,12 +511,75 @@ | ||
| 525 | 511 | ); |
| 526 | 512 | } |
| 527 | 513 | |
| 528 | 514 | /** |
| 529 | - * A hook handler for adding admin pages and subpages. | |
| 515 | + * Initializes assets for network admin pages. | |
| 516 | + * | |
| 517 | + * @since 15.7 | |
| 530 | 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 | + */ | |
| 531 | 577 | public function wrap_network_admin_page() { |
| 532 | - 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>'; | |
| 533 | 582 | } |
| 534 | 583 | |
| 535 | 584 | /** |
| 536 | 585 | * Handles the displaying of all sites on the network that are |
| @@ -540,9 +589,8 @@ | ||
| 540 | 589 | * @see Jetpack_Network::jetpack_sites_list() |
| 541 | 590 | */ |
| 542 | 591 | public function network_admin_page() { |
| 543 | 592 | global $current_site; |
| 544 | - $this->network_admin_page_header(); | |
| 545 | 593 | |
| 546 | 594 | $jp = Jetpack::init(); |
| 547 | 595 | |
| 548 | 596 | // We should be, but ensure we are on the main blog. |
| @@ -594,8 +642,9 @@ | ||
| 594 | 642 | /** |
| 595 | 643 | * Fires when the Jetpack > Settings page is saved. |
| 596 | 644 | * |
| 597 | 645 | * @since 2.9 |
| 646 | + * @return never | |
| 598 | 647 | */ |
| 599 | 648 | public function save_network_settings_page() { |
| 600 | 649 | |
| 601 | 650 | if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'jetpack-network-settings' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| @@ -605,9 +654,9 @@ | ||
| 605 | 654 | array( 'page' => 'jetpack-settings' ), |
| 606 | 655 | network_admin_url( 'admin.php' ) |
| 607 | 656 | ) |
| 608 | 657 | ); |
| 609 | - exit(); | |
| 658 | + exit( 0 ); | |
| 610 | 659 | } |
| 611 | 660 | |
| 612 | 661 | // Try to save the Protect allow list before anything else, since that action can result in errors. |
| 613 | 662 | $allow_list = isset( $_POST['global-allow-list'] ) ? filter_var( wp_unslash( $_POST['global-allow-list'] ) ) : ''; |
| @@ -623,9 +672,9 @@ | ||
| 623 | 672 | ), |
| 624 | 673 | network_admin_url( 'admin.php' ) |
| 625 | 674 | ) |
| 626 | 675 | ); |
| 627 | - exit(); | |
| 676 | + exit( 0 ); | |
| 628 | 677 | } |
| 629 | 678 | |
| 630 | 679 | /* |
| 631 | 680 | * Fields |
| @@ -657,16 +706,19 @@ | ||
| 657 | 706 | ), |
| 658 | 707 | network_admin_url( 'admin.php' ) |
| 659 | 708 | ) |
| 660 | 709 | ); |
| 661 | - exit(); | |
| 710 | + exit( 0 ); | |
| 662 | 711 | } |
| 663 | 712 | |
| 664 | 713 | /** |
| 665 | - * A hook handler for adding admin pages and subpages. | |
| 714 | + * Renders the Network Settings page with the unified admin header. | |
| 666 | 715 | */ |
| 667 | 716 | public function wrap_render_network_admin_settings_page() { |
| 668 | - 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>'; | |
| 669 | 721 | } |
| 670 | 722 | |
| 671 | 723 | /** |
| 672 | 724 | * A hook rendering the admin settings page. |
| @@ -671,9 +723,8 @@ | ||
| 671 | 723 | /** |
| 672 | 724 | * A hook rendering the admin settings page. |
| 673 | 725 | */ |
| 674 | 726 | public function render_network_admin_settings_page() { |
| 675 | - $this->network_admin_page_header(); | |
| 676 | 727 | $options = wp_parse_args( get_site_option( $this->settings_name ), $this->setting_defaults ); |
| 677 | 728 | |
| 678 | 729 | $modules = array(); |
| 679 | 730 | $module_slugs = Jetpack::get_available_modules(); |