"Fossies" - the Fresh Open Source Software Archive

Member "wordpress/wp-admin/includes/network.php" (5 Jan 2021, 25119 Bytes) of package /linux/www/wordpress-5.7-RC1.tar.gz:


The requested HTML page contains a <FORM> tag that is unusable on "Fossies" in "automatic" (rendered) mode so that page is shown as HTML source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "network.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.6.2_vs_5.7-RC1.

    1 <?php
    2 /**
    3  * WordPress Network Administration API.
    4  *
    5  * @package WordPress
    6  * @subpackage Administration
    7  * @since 4.4.0
    8  */
    9 
   10 /**
   11  * Check for an existing network.
   12  *
   13  * @since 3.0.0
   14  *
   15  * @global wpdb $wpdb WordPress database abstraction object.
   16  *
   17  * @return string|false Base domain if network exists, otherwise false.
   18  */
   19 function network_domain_check() {
   20     global $wpdb;
   21 
   22     $sql = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $wpdb->site ) );
   23     if ( $wpdb->get_var( $sql ) ) {
   24         return $wpdb->get_var( "SELECT domain FROM $wpdb->site ORDER BY id ASC LIMIT 1" );
   25     }
   26     return false;
   27 }
   28 
   29 /**
   30  * Allow subdomain installation
   31  *
   32  * @since 3.0.0
   33  * @return bool Whether subdomain installation is allowed
   34  */
   35 function allow_subdomain_install() {
   36     $domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'home' ) );
   37     if ( parse_url( get_option( 'home' ), PHP_URL_PATH ) || 'localhost' === $domain || preg_match( '|^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$|', $domain ) ) {
   38         return false;
   39     }
   40 
   41     return true;
   42 }
   43 
   44 /**
   45  * Allow subdirectory installation.
   46  *
   47  * @since 3.0.0
   48  *
   49  * @global wpdb $wpdb WordPress database abstraction object.
   50  *
   51  * @return bool Whether subdirectory installation is allowed
   52  */
   53 function allow_subdirectory_install() {
   54     global $wpdb;
   55 
   56     /**
   57      * Filters whether to enable the subdirectory installation feature in Multisite.
   58      *
   59      * @since 3.0.0
   60      *
   61      * @param bool $allow Whether to enable the subdirectory installation feature in Multisite.
   62      *                    Default false.
   63      */
   64     if ( apply_filters( 'allow_subdirectory_install', false ) ) {
   65         return true;
   66     }
   67 
   68     if ( defined( 'ALLOW_SUBDIRECTORY_INSTALL' ) && ALLOW_SUBDIRECTORY_INSTALL ) {
   69         return true;
   70     }
   71 
   72     $post = $wpdb->get_row( "SELECT ID FROM $wpdb->posts WHERE post_date < DATE_SUB(NOW(), INTERVAL 1 MONTH) AND post_status = 'publish'" );
   73     if ( empty( $post ) ) {
   74         return true;
   75     }
   76 
   77     return false;
   78 }
   79 
   80 /**
   81  * Get base domain of network.
   82  *
   83  * @since 3.0.0
   84  * @return string Base domain.
   85  */
   86 function get_clean_basedomain() {
   87     $existing_domain = network_domain_check();
   88     if ( $existing_domain ) {
   89         return $existing_domain;
   90     }
   91     $domain = preg_replace( '|https?://|', '', get_option( 'siteurl' ) );
   92     $slash  = strpos( $domain, '/' );
   93     if ( $slash ) {
   94         $domain = substr( $domain, 0, $slash );
   95     }
   96     return $domain;
   97 }
   98 
   99 /**
  100  * Prints step 1 for Network installation process.
  101  *
  102  * @todo Realistically, step 1 should be a welcome screen explaining what a Network is and such.
  103  *       Navigating to Tools > Network should not be a sudden "Welcome to a new install process!
  104  *       Fill this out and click here." See also contextual help todo.
  105  *
  106  * @since 3.0.0
  107  *
  108  * @global bool $is_apache
  109  *
  110  * @param false|WP_Error $errors Optional. Error object. Default false.
  111  */
  112 function network_step1( $errors = false ) {
  113     global $is_apache;
  114 
  115     if ( defined( 'DO_NOT_UPGRADE_GLOBAL_TABLES' ) ) {
  116         echo '<div class="error"><p><strong>' . __( 'Error:' ) . '</strong> ' . sprintf(
  117             /* translators: %s: DO_NOT_UPGRADE_GLOBAL_TABLES */
  118             __( 'The constant %s cannot be defined when creating a network.' ),
  119             '<code>DO_NOT_UPGRADE_GLOBAL_TABLES</code>'
  120         ) . '</p></div>';
  121         echo '</div>';
  122         require_once ABSPATH . 'wp-admin/admin-footer.php';
  123         die();
  124     }
  125 
  126     $active_plugins = get_option( 'active_plugins' );
  127     if ( ! empty( $active_plugins ) ) {
  128         echo '<div class="notice notice-warning"><p><strong>' . __( 'Warning:' ) . '</strong> ' . sprintf(
  129             /* translators: %s: URL to Plugins screen. */
  130             __( 'Please <a href="%s">deactivate your plugins</a> before enabling the Network feature.' ),
  131             admin_url( 'plugins.php?plugin_status=active' )
  132         ) . '</p></div>';
  133         echo '<p>' . __( 'Once the network is created, you may reactivate your plugins.' ) . '</p>';
  134         echo '</div>';
  135         require_once ABSPATH . 'wp-admin/admin-footer.php';
  136         die();
  137     }
  138 
  139     $hostname  = get_clean_basedomain();
  140     $has_ports = strstr( $hostname, ':' );
  141     if ( ( false !== $has_ports && ! in_array( $has_ports, array( ':80', ':443' ), true ) ) ) {
  142         echo '<div class="error"><p><strong>' . __( 'Error:' ) . '</strong> ' . __( 'You cannot install a network of sites with your server address.' ) . '</p></div>';
  143         echo '<p>' . sprintf(
  144             /* translators: %s: Port number. */
  145             __( 'You cannot use port numbers such as %s.' ),
  146             '<code>' . $has_ports . '</code>'
  147         ) . '</p>';
  148         echo '<a href="' . esc_url( admin_url() ) . '">' . __( 'Go to Dashboard' ) . '</a>';
  149         echo '</div>';
  150         require_once ABSPATH . 'wp-admin/admin-footer.php';
  151         die();
  152     }
  153 
  154     echo '<form method="post">';
  155 
  156     wp_nonce_field( 'install-network-1' );
  157 
  158     $error_codes = array();
  159     if ( is_wp_error( $errors ) ) {
  160         echo '<div class="error"><p><strong>' . __( 'Error: The network could not be created.' ) . '</strong></p>';
  161         foreach ( $errors->get_error_messages() as $error ) {
  162             echo "<p>$error</p>";
  163         }
  164         echo '</div>';
  165         $error_codes = $errors->get_error_codes();
  166     }
  167 
  168     if ( ! empty( $_POST['sitename'] ) && ! in_array( 'empty_sitename', $error_codes, true ) ) {
  169         $site_name = $_POST['sitename'];
  170     } else {
  171         /* translators: %s: Default network title. */
  172         $site_name = sprintf( __( '%s Sites' ), get_option( 'blogname' ) );
  173     }
  174 
  175     if ( ! empty( $_POST['email'] ) && ! in_array( 'invalid_email', $error_codes, true ) ) {
  176         $admin_email = $_POST['email'];
  177     } else {
  178         $admin_email = get_option( 'admin_email' );
  179     }
  180     ?>
  181     <p><?php _e( 'Welcome to the Network installation process!' ); ?></p>
  182     <p><?php _e( 'Fill in the information below and you&#8217;ll be on your way to creating a network of WordPress sites. We will create configuration files in the next step.' ); ?></p>
  183     <?php
  184 
  185     if ( isset( $_POST['subdomain_install'] ) ) {
  186         $subdomain_install = (bool) $_POST['subdomain_install'];
  187     } elseif ( apache_mod_loaded( 'mod_rewrite' ) ) { // Assume nothing.
  188         $subdomain_install = true;
  189     } elseif ( ! allow_subdirectory_install() ) {
  190         $subdomain_install = true;
  191     } else {
  192         $subdomain_install = false;
  193         $got_mod_rewrite   = got_mod_rewrite();
  194         if ( $got_mod_rewrite ) { // Dangerous assumptions.
  195             echo '<div class="updated inline"><p><strong>' . __( 'Note:' ) . '</strong> ';
  196             printf(
  197                 /* translators: %s: mod_rewrite */
  198                 __( 'Please make sure the Apache %s module is installed as it will be used at the end of this installation.' ),
  199                 '<code>mod_rewrite</code>'
  200             );
  201             echo '</p>';
  202         } elseif ( $is_apache ) {
  203             echo '<div class="error inline"><p><strong>' . __( 'Warning:' ) . '</strong> ';
  204             printf(
  205                 /* translators: %s: mod_rewrite */
  206                 __( 'It looks like the Apache %s module is not installed.' ),
  207                 '<code>mod_rewrite</code>'
  208             );
  209             echo '</p>';
  210         }
  211 
  212         if ( $got_mod_rewrite || $is_apache ) { // Protect against mod_rewrite mimicry (but ! Apache).
  213             echo '<p>';
  214             printf(
  215                 /* translators: 1: mod_rewrite, 2: mod_rewrite documentation URL, 3: Google search for mod_rewrite. */
  216                 __( 'If %1$s is disabled, ask your administrator to enable that module, or look at the <a href="%2$s">Apache documentation</a> or <a href="%3$s">elsewhere</a> for help setting it up.' ),
  217                 '<code>mod_rewrite</code>',
  218                 'https://httpd.apache.org/docs/mod/mod_rewrite.html',
  219                 'https://www.google.com/search?q=apache+mod_rewrite'
  220             );
  221             echo '</p></div>';
  222         }
  223     }
  224 
  225     if ( allow_subdomain_install() && allow_subdirectory_install() ) :
  226         ?>
  227         <h3><?php esc_html_e( 'Addresses of Sites in your Network' ); ?></h3>
  228         <p><?php _e( 'Please choose whether you would like sites in your WordPress network to use sub-domains or sub-directories.' ); ?>
  229             <strong><?php _e( 'You cannot change this later.' ); ?></strong></p>
  230         <p><?php _e( 'You will need a wildcard DNS record if you are going to use the virtual host (sub-domain) functionality.' ); ?></p>
  231         <?php // @todo Link to an MS readme? ?>
  232         <table class="form-table" role="presentation">
  233             <tr>
  234                 <th><label><input type="radio" name="subdomain_install" value="1"<?php checked( $subdomain_install ); ?> /> <?php _e( 'Sub-domains' ); ?></label></th>
  235                 <td>
  236                 <?php
  237                 printf(
  238                     /* translators: 1: Host name. */
  239                     _x( 'like <code>site1.%1$s</code> and <code>site2.%1$s</code>', 'subdomain examples' ),
  240                     $hostname
  241                 );
  242                 ?>
  243                 </td>
  244             </tr>
  245             <tr>
  246                 <th><label><input type="radio" name="subdomain_install" value="0"<?php checked( ! $subdomain_install ); ?> /> <?php _e( 'Sub-directories' ); ?></label></th>
  247                 <td>
  248                 <?php
  249                 printf(
  250                     /* translators: 1: Host name. */
  251                     _x( 'like <code>%1$s/site1</code> and <code>%1$s/site2</code>', 'subdirectory examples' ),
  252                     $hostname
  253                 );
  254                 ?>
  255                 </td>
  256             </tr>
  257         </table>
  258 
  259         <?php
  260     endif;
  261 
  262     if ( WP_CONTENT_DIR !== ABSPATH . 'wp-content' && ( allow_subdirectory_install() || ! allow_subdomain_install() ) ) {
  263         echo '<div class="error inline"><p><strong>' . __( 'Warning:' ) . '</strong> ' . __( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</p></div>';
  264     }
  265 
  266     $is_www = ( 0 === strpos( $hostname, 'www.' ) );
  267     if ( $is_www ) :
  268         ?>
  269         <h3><?php esc_html_e( 'Server Address' ); ?></h3>
  270         <p>
  271         <?php
  272         printf(
  273             /* translators: 1: Site URL, 2: Host name, 3: www. */
  274             __( 'We recommend you change your site domain to %1$s before enabling the network feature. It will still be possible to visit your site using the %3$s prefix with an address like %2$s but any links will not have the %3$s prefix.' ),
  275             '<code>' . substr( $hostname, 4 ) . '</code>',
  276             '<code>' . $hostname . '</code>',
  277             '<code>www</code>'
  278         );
  279         ?>
  280         </p>
  281         <table class="form-table" role="presentation">
  282             <tr>
  283             <th scope='row'><?php esc_html_e( 'Server Address' ); ?></th>
  284             <td>
  285                 <?php
  286                     printf(
  287                         /* translators: %s: Host name. */
  288                         __( 'The internet address of your network will be %s.' ),
  289                         '<code>' . $hostname . '</code>'
  290                     );
  291                 ?>
  292                 </td>
  293             </tr>
  294         </table>
  295         <?php endif; ?>
  296 
  297         <h3><?php esc_html_e( 'Network Details' ); ?></h3>
  298         <table class="form-table" role="presentation">
  299         <?php if ( 'localhost' === $hostname ) : ?>
  300             <tr>
  301                 <th scope="row"><?php esc_html_e( 'Sub-directory Installation' ); ?></th>
  302                 <td>
  303                 <?php
  304                     printf(
  305                         /* translators: 1: localhost, 2: localhost.localdomain */
  306                         __( 'Because you are using %1$s, the sites in your WordPress network must use sub-directories. Consider using %2$s if you wish to use sub-domains.' ),
  307                         '<code>localhost</code>',
  308                         '<code>localhost.localdomain</code>'
  309                     );
  310                     // Uh oh:
  311                 if ( ! allow_subdirectory_install() ) {
  312                     echo ' <strong>' . __( 'Warning:' ) . ' ' . __( 'The main site in a sub-directory installation will need to use a modified permalink structure, potentially breaking existing links.' ) . '</strong>';
  313                 }
  314                 ?>
  315                 </td>
  316             </tr>
  317         <?php elseif ( ! allow_subdomain_install() ) : ?>
  318             <tr>
  319                 <th scope="row"><?php esc_html_e( 'Sub-directory Installation' ); ?></th>
  320                 <td>
  321                 <?php
  322                     _e( 'Because your installation is in a directory, the sites in your WordPress network must use sub-directories.' );
  323                     // Uh oh:
  324                 if ( ! allow_subdirectory_install() ) {
  325                     echo ' <strong>' . __( 'Warning:' ) . ' ' . __( 'The main site in a sub-directory installation will need to use a modified permalink structure, potentially breaking existing links.' ) . '</strong>';
  326                 }
  327                 ?>
  328                 </td>
  329             </tr>
  330         <?php elseif ( ! allow_subdirectory_install() ) : ?>
  331             <tr>
  332                 <th scope="row"><?php esc_html_e( 'Sub-domain Installation' ); ?></th>
  333                 <td>
  334                 <?php
  335                 _e( 'Because your installation is not new, the sites in your WordPress network must use sub-domains.' );
  336                     echo ' <strong>' . __( 'The main site in a sub-directory installation will need to use a modified permalink structure, potentially breaking existing links.' ) . '</strong>';
  337                 ?>
  338                 </td>
  339             </tr>
  340         <?php endif; ?>
  341         <?php if ( ! $is_www ) : ?>
  342             <tr>
  343                 <th scope='row'><?php esc_html_e( 'Server Address' ); ?></th>
  344                 <td>
  345                     <?php
  346                     printf(
  347                         /* translators: %s: Host name. */
  348                         __( 'The internet address of your network will be %s.' ),
  349                         '<code>' . $hostname . '</code>'
  350                     );
  351                     ?>
  352                 </td>
  353             </tr>
  354         <?php endif; ?>
  355             <tr>
  356                 <th scope='row'><label for="sitename"><?php esc_html_e( 'Network Title' ); ?></label></th>
  357                 <td>
  358                     <input name='sitename' id='sitename' type='text' size='45' value='<?php echo esc_attr( $site_name ); ?>' />
  359                     <p class="description">
  360                         <?php _e( 'What would you like to call your network?' ); ?>
  361                     </p>
  362                 </td>
  363             </tr>
  364             <tr>
  365                 <th scope='row'><label for="email"><?php esc_html_e( 'Network Admin Email' ); ?></label></th>
  366                 <td>
  367                     <input name='email' id='email' type='text' size='45' value='<?php echo esc_attr( $admin_email ); ?>' />
  368                     <p class="description">
  369                         <?php _e( 'Your email address.' ); ?>
  370                     </p>
  371                 </td>
  372             </tr>
  373         </table>
  374         <?php submit_button( __( 'Install' ), 'primary', 'submit' ); ?>
  375     </form>
  376     <?php
  377 }
  378 
  379 /**
  380  * Prints step 2 for Network installation process.
  381  *
  382  * @since 3.0.0
  383  *
  384  * @global wpdb $wpdb     WordPress database abstraction object.
  385  * @global bool $is_nginx Whether the server software is Nginx or something else.
  386  *
  387  * @param false|WP_Error $errors Optional. Error object. Default false.
  388  */
  389 function network_step2( $errors = false ) {
  390     global $wpdb, $is_nginx;
  391 
  392     $hostname          = get_clean_basedomain();
  393     $slashed_home      = trailingslashit( get_option( 'home' ) );
  394     $base              = parse_url( $slashed_home, PHP_URL_PATH );
  395     $document_root_fix = str_replace( '\\', '/', realpath( $_SERVER['DOCUMENT_ROOT'] ) );
  396     $abspath_fix       = str_replace( '\\', '/', ABSPATH );
  397     $home_path         = 0 === strpos( $abspath_fix, $document_root_fix ) ? $document_root_fix . $base : get_home_path();
  398     $wp_siteurl_subdir = preg_replace( '#^' . preg_quote( $home_path, '#' ) . '#', '', $abspath_fix );
  399     $rewrite_base      = ! empty( $wp_siteurl_subdir ) ? ltrim( trailingslashit( $wp_siteurl_subdir ), '/' ) : '';
  400 
  401     $location_of_wp_config = $abspath_fix;
  402     if ( ! file_exists( ABSPATH . 'wp-config.php' ) && file_exists( dirname( ABSPATH ) . '/wp-config.php' ) ) {
  403         $location_of_wp_config = dirname( $abspath_fix );
  404     }
  405     $location_of_wp_config = trailingslashit( $location_of_wp_config );
  406 
  407     // Wildcard DNS message.
  408     if ( is_wp_error( $errors ) ) {
  409         echo '<div class="error">' . $errors->get_error_message() . '</div>';
  410     }
  411 
  412     if ( $_POST ) {
  413         if ( allow_subdomain_install() ) {
  414             $subdomain_install = allow_subdirectory_install() ? ! empty( $_POST['subdomain_install'] ) : true;
  415         } else {
  416             $subdomain_install = false;
  417         }
  418     } else {
  419         if ( is_multisite() ) {
  420             $subdomain_install = is_subdomain_install();
  421             ?>
  422     <p><?php _e( 'The original configuration steps are shown here for reference.' ); ?></p>
  423             <?php
  424         } else {
  425             $subdomain_install = (bool) $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" );
  426             ?>
  427     <div class="error"><p><strong><?php _e( 'Warning:' ); ?></strong> <?php _e( 'An existing WordPress network was detected.' ); ?></p></div>
  428     <p><?php _e( 'Please complete the configuration steps. To create a new network, you will need to empty or remove the network database tables.' ); ?></p>
  429             <?php
  430         }
  431     }
  432 
  433     $subdir_match          = $subdomain_install ? '' : '([_0-9a-zA-Z-]+/)?';
  434     $subdir_replacement_01 = $subdomain_install ? '' : '$1';
  435     $subdir_replacement_12 = $subdomain_install ? '$1' : '$2';
  436 
  437     if ( $_POST || ! is_multisite() ) {
  438         ?>
  439         <h3><?php esc_html_e( 'Enabling the Network' ); ?></h3>
  440         <p><?php _e( 'Complete the following steps to enable the features for creating a network of sites.' ); ?></p>
  441         <div class="notice notice-warning inline"><p>
  442         <?php
  443         if ( file_exists( $home_path . '.htaccess' ) ) {
  444             echo '<strong>' . __( 'Caution:' ) . '</strong> ';
  445             printf(
  446                 /* translators: 1: wp-config.php, 2: .htaccess */
  447                 __( 'We recommend you back up your existing %1$s and %2$s files.' ),
  448                 '<code>wp-config.php</code>',
  449                 '<code>.htaccess</code>'
  450             );
  451         } elseif ( file_exists( $home_path . 'web.config' ) ) {
  452             echo '<strong>' . __( 'Caution:' ) . '</strong> ';
  453             printf(
  454                 /* translators: 1: wp-config.php, 2: web.config */
  455                 __( 'We recommend you back up your existing %1$s and %2$s files.' ),
  456                 '<code>wp-config.php</code>',
  457                 '<code>web.config</code>'
  458             );
  459         } else {
  460             echo '<strong>' . __( 'Caution:' ) . '</strong> ';
  461             printf(
  462                 /* translators: %s: wp-config.php */
  463                 __( 'We recommend you back up your existing %s file.' ),
  464                 '<code>wp-config.php</code>'
  465             );
  466         }
  467         ?>
  468         </p></div>
  469         <?php
  470     }
  471     ?>
  472     <ol>
  473         <li><p>
  474         <?php
  475         printf(
  476             /* translators: 1: wp-config.php, 2: Location of wp-config file, 3: Translated version of "That's all, stop editing! Happy publishing." */
  477             __( 'Add the following to your %1$s file in %2$s <strong>above</strong> the line reading %3$s:' ),
  478             '<code>wp-config.php</code>',
  479             '<code>' . $location_of_wp_config . '</code>',
  480             /*
  481              * translators: This string should only be translated if wp-config-sample.php is localized.
  482              * You can check the localized release package or
  483              * https://i18n.svn.wordpress.org/<locale code>/branches/<wp version>/dist/wp-config-sample.php
  484              */
  485             '<code>/* ' . __( 'That&#8217;s all, stop editing! Happy publishing.' ) . ' */</code>'
  486         );
  487         ?>
  488         </p>
  489         <textarea class="code" readonly="readonly" cols="100" rows="7">
  490 define('MULTISITE', true);
  491 define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>);
  492 define('DOMAIN_CURRENT_SITE', '<?php echo $hostname; ?>');
  493 define('PATH_CURRENT_SITE', '<?php echo $base; ?>');
  494 define('SITE_ID_CURRENT_SITE', 1);
  495 define('BLOG_ID_CURRENT_SITE', 1);
  496 </textarea>
  497         <?php
  498         $keys_salts = array(
  499             'AUTH_KEY'         => '',
  500             'SECURE_AUTH_KEY'  => '',
  501             'LOGGED_IN_KEY'    => '',
  502             'NONCE_KEY'        => '',
  503             'AUTH_SALT'        => '',
  504             'SECURE_AUTH_SALT' => '',
  505             'LOGGED_IN_SALT'   => '',
  506             'NONCE_SALT'       => '',
  507         );
  508         foreach ( $keys_salts as $c => $v ) {
  509             if ( defined( $c ) ) {
  510                 unset( $keys_salts[ $c ] );
  511             }
  512         }
  513 
  514         if ( ! empty( $keys_salts ) ) {
  515             $keys_salts_str = '';
  516             $from_api       = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
  517             if ( is_wp_error( $from_api ) ) {
  518                 foreach ( $keys_salts as $c => $v ) {
  519                     $keys_salts_str .= "\ndefine( '$c', '" . wp_generate_password( 64, true, true ) . "' );";
  520                 }
  521             } else {
  522                 $from_api = explode( "\n", wp_remote_retrieve_body( $from_api ) );
  523                 foreach ( $keys_salts as $c => $v ) {
  524                     $keys_salts_str .= "\ndefine( '$c', '" . substr( array_shift( $from_api ), 28, 64 ) . "' );";
  525                 }
  526             }
  527             $num_keys_salts = count( $keys_salts );
  528             ?>
  529         <p>
  530             <?php
  531             if ( 1 === $num_keys_salts ) {
  532                 printf(
  533                     /* translators: %s: wp-config.php */
  534                     __( 'This unique authentication key is also missing from your %s file.' ),
  535                     '<code>wp-config.php</code>'
  536                 );
  537             } else {
  538                 printf(
  539                     /* translators: %s: wp-config.php */
  540                     __( 'These unique authentication keys are also missing from your %s file.' ),
  541                     '<code>wp-config.php</code>'
  542                 );
  543             }
  544             ?>
  545             <?php _e( 'To make your installation more secure, you should also add:' ); ?>
  546         </p>
  547         <textarea class="code" readonly="readonly" cols="100" rows="<?php echo $num_keys_salts; ?>"><?php echo esc_textarea( $keys_salts_str ); ?></textarea>
  548             <?php
  549         }
  550         ?>
  551         </li>
  552     <?php
  553     if ( iis7_supports_permalinks() ) :
  554         // IIS doesn't support RewriteBase, all your RewriteBase are belong to us.
  555         $iis_subdir_match       = ltrim( $base, '/' ) . $subdir_match;
  556         $iis_rewrite_base       = ltrim( $base, '/' ) . $rewrite_base;
  557         $iis_subdir_replacement = $subdomain_install ? '' : '{R:1}';
  558 
  559         $web_config_file = '<?xml version="1.0" encoding="UTF-8"?>
  560 <configuration>
  561     <system.webServer>
  562         <rewrite>
  563             <rules>
  564                 <rule name="WordPress Rule 1" stopProcessing="true">
  565                     <match url="^index\.php$" ignoreCase="false" />
  566                     <action type="None" />
  567                 </rule>';
  568         if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) {
  569             $web_config_file .= '
  570                 <rule name="WordPress Rule for Files" stopProcessing="true">
  571                     <match url="^' . $iis_subdir_match . 'files/(.+)" ignoreCase="false" />
  572                     <action type="Rewrite" url="' . $iis_rewrite_base . WPINC . '/ms-files.php?file={R:1}" appendQueryString="false" />
  573                 </rule>';
  574         }
  575             $web_config_file .= '
  576                 <rule name="WordPress Rule 2" stopProcessing="true">
  577                     <match url="^' . $iis_subdir_match . 'wp-admin$" ignoreCase="false" />
  578                     <action type="Redirect" url="' . $iis_subdir_replacement . 'wp-admin/" redirectType="Permanent" />
  579                 </rule>
  580                 <rule name="WordPress Rule 3" stopProcessing="true">
  581                     <match url="^" ignoreCase="false" />
  582                     <conditions logicalGrouping="MatchAny">
  583                         <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
  584                         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
  585                     </conditions>
  586                     <action type="None" />
  587                 </rule>
  588                 <rule name="WordPress Rule 4" stopProcessing="true">
  589                     <match url="^' . $iis_subdir_match . '(wp-(content|admin|includes).*)" ignoreCase="false" />
  590                     <action type="Rewrite" url="' . $iis_rewrite_base . '{R:1}" />
  591                 </rule>
  592                 <rule name="WordPress Rule 5" stopProcessing="true">
  593                     <match url="^' . $iis_subdir_match . '([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
  594                     <action type="Rewrite" url="' . $iis_rewrite_base . '{R:2}" />
  595                 </rule>
  596                 <rule name="WordPress Rule 6" stopProcessing="true">
  597                     <match url="." ignoreCase="false" />
  598                     <action type="Rewrite" url="index.php" />
  599                 </rule>
  600             </rules>
  601         </rewrite>
  602     </system.webServer>
  603 </configuration>
  604 ';
  605 
  606             echo '<li><p>';
  607             printf(
  608                 /* translators: 1: File name (.htaccess or web.config), 2: File path. */
  609                 __( 'Add the following to your %1$s file in %2$s, <strong>replacing</strong> other WordPress rules:' ),
  610                 '<code>web.config</code>',
  611                 '<code>' . $home_path . '</code>'
  612             );
  613         echo '</p>';
  614         if ( ! $subdomain_install && WP_CONTENT_DIR !== ABSPATH . 'wp-content' ) {
  615             echo '<p><strong>' . __( 'Warning:' ) . ' ' . __( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</strong></p>';
  616         }
  617         ?>
  618         <textarea class="code" readonly="readonly" cols="100" rows="20"><?php echo esc_textarea( $web_config_file ); ?></textarea>
  619         </li>
  620     </ol>
  621 
  622         <?php
  623     elseif ( $is_nginx ) : // End iis7_supports_permalinks(). Link to Nginx documentation instead:
  624 
  625         echo '<li><p>';
  626         printf(
  627             /* translators: %s: Documentation URL. */
  628             __( 'It seems your network is running with Nginx web server. <a href="%s">Learn more about further configuration</a>.' ),
  629             __( 'https://wordpress.org/support/article/nginx/' )
  630         );
  631         echo '</p></li>';
  632 
  633     else : // End $is_nginx. Construct an .htaccess file instead:
  634 
  635         $ms_files_rewriting = '';
  636         if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) {
  637             $ms_files_rewriting  = "\n# uploaded files\nRewriteRule ^";
  638             $ms_files_rewriting .= $subdir_match . "files/(.+) {$rewrite_base}" . WPINC . "/ms-files.php?file={$subdir_replacement_12} [L]" . "\n";
  639         }
  640 
  641         $htaccess_file = <<<EOF
  642 RewriteEngine On
  643 RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
  644 RewriteBase {$base}
  645 RewriteRule ^index\.php$ - [L]
  646 {$ms_files_rewriting}
  647 # add a trailing slash to /wp-admin
  648 RewriteRule ^{$subdir_match}wp-admin$ {$subdir_replacement_01}wp-admin/ [R=301,L]
  649 
  650 RewriteCond %{REQUEST_FILENAME} -f [OR]
  651 RewriteCond %{REQUEST_FILENAME} -d
  652 RewriteRule ^ - [L]
  653 RewriteRule ^{$subdir_match}(wp-(content|admin|includes).*) {$rewrite_base}{$subdir_replacement_12} [L]
  654 RewriteRule ^{$subdir_match}(.*\.php)$ {$rewrite_base}$subdir_replacement_12 [L]
  655 RewriteRule . index.php [L]
  656 
  657 EOF;
  658 
  659         echo '<li><p>';
  660         printf(
  661             /* translators: 1: File name (.htaccess or web.config), 2: File path. */
  662             __( 'Add the following to your %1$s file in %2$s, <strong>replacing</strong> other WordPress rules:' ),
  663             '<code>.htaccess</code>',
  664             '<code>' . $home_path . '</code>'
  665         );
  666         echo '</p>';
  667         if ( ! $subdomain_install && WP_CONTENT_DIR !== ABSPATH . 'wp-content' ) {
  668             echo '<p><strong>' . __( 'Warning:' ) . ' ' . __( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</strong></p>';
  669         }
  670         ?>
  671         <textarea class="code" readonly="readonly" cols="100" rows="<?php echo substr_count( $htaccess_file, "\n" ) + 1; ?>"><?php echo esc_textarea( $htaccess_file ); ?></textarea>
  672         </li>
  673     </ol>
  674 
  675         <?php
  676     endif; // End IIS/Nginx/Apache code branches.
  677 
  678     if ( ! is_multisite() ) {
  679         ?>
  680         <p><?php _e( 'Once you complete these steps, your network is enabled and configured. You will have to log in again.' ); ?> <a href="<?php echo esc_url( wp_login_url() ); ?>"><?php _e( 'Log In' ); ?></a></p>
  681         <?php
  682     }
  683 }