PageRenderTime 39ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-admin/includes/network.php

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