'network_wpcom_blog_id' => $network_wpcom_blog_id,
'user_id' => get_current_user_id(),
* Use the subsite's registration date as the site creation date.
* This is in contrast to regular standalone sites, where we use the helper
* `Jetpack::get_assumed_site_creation_date()` to assume the site's creation date.
'site_created' => $blog_details->registered,
* A hook handler for adding admin pages and subpages.
public function wrap_network_admin_page() {
Jetpack_Admin_Page::wrap_ui( array( $this, 'network_admin_page' ) );
* Handles the displaying of all sites on the network that are
* dis/connected to Jetpack
* @see Jetpack_Network::jetpack_sites_list()
public function network_admin_page() {
$this->network_admin_page_header();
// We should be, but ensure we are on the main blog.
switch_to_blog( $current_site->blog_id );
$main_active = $jp->is_connection_ready();
// If we are in dev mode, just show the notice and bail.
if ( ( new Status() )->is_offline_mode() ) {
Jetpack::show_development_mode_notice();
* Ensure the main blog is connected as all other subsite blog
* connections will feed off this one
$data = array( 'url' => $jp->build_connect_url() );
Jetpack::init()->load_view( 'admin/must-connect-main-blog.php', $data );
require_once __DIR__ . '/class.jetpack-network-sites-list-table.php';
$network_sites_table = new Jetpack_Network_Sites_List_Table();
echo '<div class="wrap"><h2>' . esc_html__( 'Sites', 'jetpack' ) . '</h2>';
echo '<form method="post">';
$network_sites_table->prepare_items();
$network_sites_table->display();
* Stylized JP header formatting
public function network_admin_page_header() {
$is_connected = Jetpack::is_connection_ready();
'is_connected' => $is_connected,
Jetpack::init()->load_view( 'admin/network-admin-header.php', $data );
* Fires when the Jetpack > Settings page is saved.
public function save_network_settings_page() {
if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'jetpack-network-settings' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// No nonce, push back to settings page.
array( 'page' => 'jetpack-settings' ),
network_admin_url( 'admin.php' )
// Try to save the Protect allow list before anything else, since that action can result in errors.
$allow_list = isset( $_POST['global-allow-list'] ) ? filter_var( wp_unslash( $_POST['global-allow-list'] ) ) : '';
$allow_list = str_replace( ' ', '', $allow_list );
$allow_list = explode( PHP_EOL, $allow_list );
$result = Brute_Force_Protection_Shared_Functions::save_allow_list( $allow_list, true );
if ( is_wp_error( $result ) ) {
'page' => 'jetpack-settings',
'error' => 'jetpack_protect_whitelist',
network_admin_url( 'admin.php' )
* auto-connect - Checkbox for global Jetpack connection
* sub-site-connection-override - Allow sub-site admins to (dis)reconnect with their own Jetpack account
if ( isset( $_POST['auto-connect'] ) ) {
$sub_site_connection_override = 0;
if ( isset( $_POST['sub-site-connection-override'] ) ) {
$sub_site_connection_override = 1;
'auto-connect' => $auto_connect,
'sub-site-connection-override' => $sub_site_connection_override,
update_site_option( $this->settings_name, $data );
'page' => 'jetpack-settings',
network_admin_url( 'admin.php' )
* A hook handler for adding admin pages and subpages.
public function wrap_render_network_admin_settings_page() {
Jetpack_Admin_Page::wrap_ui( array( $this, 'render_network_admin_settings_page' ) );
* A hook rendering the admin settings page.
public function render_network_admin_settings_page() {
$this->network_admin_page_header();
$options = wp_parse_args( get_site_option( $this->settings_name ), $this->setting_defaults );
$module_slugs = Jetpack::get_available_modules();
foreach ( $module_slugs as $slug ) {
$module = Jetpack::get_module( $slug );
$module['module'] = $slug;
usort( $modules, array( 'Jetpack', 'sort_modules' ) );
if ( ! isset( $options['modules'] ) ) {
$options['modules'] = $modules;
'jetpack_protect_whitelist' => Brute_Force_Protection_Shared_Functions::format_allow_list(),
Jetpack::init()->load_view( 'admin/network-settings.php', $data );
* Updates a site wide option
* @param string $key option name.
* @param mixed $value option value.
public function update_option( $key, $value ) {
$options = get_site_option( $this->settings_name, $this->setting_defaults );
$options[ $key ] = $value;
return update_site_option( $this->settings_name, $options );
* Retrieves a site wide option
* @param string $name - Name of the option in the database.
public function get_option( $name ) {
$options = get_site_option( $this->settings_name, $this->setting_defaults );
$options = wp_parse_args( $options, $this->setting_defaults );
if ( ! isset( $options[ $name ] ) ) {
$options[ $name ] = null;
return $options[ $name ];