Make Multisite work when WordPress is installed in a subdirectory. You can now have WordPress Multisite as an SVN external or a Git submodule! props johnjamesjacoby, evansolomon, duck_, jakemgold, nacin, markjaquith. see #19796

git-svn-id: http://core.svn.wordpress.org/trunk@22042 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Mark Jaquith 2012-09-27 06:07:21 +00:00
parent 336cd3d632
commit e3dc0220ff
3 changed files with 64 additions and 162 deletions

View File

@ -51,8 +51,8 @@ function network_domain_check() {
* @return bool Whether subdomain install is allowed * @return bool Whether subdomain install is allowed
*/ */
function allow_subdomain_install() { function allow_subdomain_install() {
$domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'siteurl' ) ); $domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'home' ) );
if( false !== strpos( $domain, '/' ) || 'localhost' == $domain || preg_match( '|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|', $domain ) ) if( parse_url( get_option( 'home' ), PHP_URL_PATH ) || 'localhost' == $domain || preg_match( '|^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$|', $domain ) )
return false; return false;
return true; return true;
@ -144,13 +144,6 @@ include( ABSPATH . 'wp-admin/admin-header.php' );
function network_step1( $errors = false ) { function network_step1( $errors = false ) {
global $is_apache; global $is_apache;
if ( get_option( 'siteurl' ) != get_option( 'home' ) ) {
echo '<div class="error"><p><strong>' . __('ERROR:') . '</strong> ' . sprintf( __( 'Your <strong>WordPress address</strong> must match your <strong>Site address</strong> before creating a Network. See <a href="%s">General Settings</a>.' ), esc_url( admin_url( 'options-general.php' ) ) ) . '</p></div>';
echo '</div>';
include ( ABSPATH . 'wp-admin/admin-footer.php' );
die();
}
if ( defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) { if ( defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) {
echo '<div class="error"><p><strong>' . __('ERROR:') . '</strong> ' . __( 'The constant DO_NOT_UPGRADE_GLOBAL_TABLES cannot be defined when creating a network.' ) . '</p></div>'; echo '<div class="error"><p><strong>' . __('ERROR:') . '</strong> ' . __( 'The constant DO_NOT_UPGRADE_GLOBAL_TABLES cannot be defined when creating a network.' ) . '</p></div>';
echo '</div>'; echo '</div>';
@ -314,11 +307,14 @@ function network_step1( $errors = false ) {
* @since 3.0.0 * @since 3.0.0
*/ */
function network_step2( $errors = false ) { function network_step2( $errors = false ) {
global $base, $wpdb; global $wpdb;
$hostname = get_clean_basedomain();
if ( ! isset( $base ) ) $hostname = get_clean_basedomain();
$base = trailingslashit( stripslashes( dirname( dirname( $_SERVER['SCRIPT_NAME'] ) ) ) ); $slashed_home = trailingslashit( get_option( 'home' ) );
$base = parse_url( $slashed_home, PHP_URL_PATH );
$wp_dir_from_root = preg_replace( '#^' . preg_quote( $_SERVER['DOCUMENT_ROOT'], '#' ) . '#', '', ABSPATH );
$wp_siteurl_subdir = trailingslashit( '/' . preg_replace( '#^' . preg_quote( $base, '#' ) . '#', '', $wp_dir_from_root ) );
$rewrite_base = ! empty( $wp_siteurl_subdir ) ? ltrim( trailingslashit( $wp_siteurl_subdir ), '/' ) : '';
// Wildcard DNS message. // Wildcard DNS message.
if ( is_wp_error( $errors ) ) if ( is_wp_error( $errors ) )
@ -344,6 +340,10 @@ function network_step2( $errors = false ) {
} }
} }
$subdir_match = $subdomain_install ? '' : '([_0-9a-zA-Z-]+/)?';
$subdir_replacement_01 = $subdomain_install ? '' : '$1';
$subdir_replacement_12 = $subdomain_install ? '$1' : '$2';
if ( $_POST || ! is_multisite() ) { if ( $_POST || ! is_multisite() ) {
?> ?>
<h3><?php esc_html_e( 'Enabling the Network' ); ?></h3> <h3><?php esc_html_e( 'Enabling the Network' ); ?></h3>
@ -361,20 +361,21 @@ function network_step2( $errors = false ) {
?> ?>
<ol> <ol>
<li><p><?php printf( __( 'Add the following to your <code>wp-config.php</code> file in <code>%s</code> <strong>above</strong> the line reading <code>/* That&#8217;s all, stop editing! Happy blogging. */</code>:' ), ABSPATH ); ?></p> <li><p><?php printf( __( 'Add the following to your <code>wp-config.php</code> file in <code>%s</code> <strong>above</strong> the line reading <code>/* That&#8217;s all, stop editing! Happy blogging. */</code>:' ), ABSPATH ); ?></p>
<textarea class="code" readonly="readonly" cols="100" rows="7"> <textarea class="code" readonly="readonly" cols="100" rows="6">
define('MULTISITE', true); define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>); define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>);
$base = '<?php echo $base; ?>';
define('DOMAIN_CURRENT_SITE', '<?php echo $hostname; ?>'); define('DOMAIN_CURRENT_SITE', '<?php echo $hostname; ?>');
define('PATH_CURRENT_SITE', '<?php echo $base; ?>'); define('PATH_CURRENT_SITE', '<?php echo $base; ?>');
define('SITE_ID_CURRENT_SITE', 1); define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);</textarea> define('BLOG_ID_CURRENT_SITE', 1);
</textarea>
<?php <?php
$keys_salts = array( 'AUTH_KEY' => '', 'SECURE_AUTH_KEY' => '', 'LOGGED_IN_KEY' => '', 'NONCE_KEY' => '', 'AUTH_SALT' => '', 'SECURE_AUTH_SALT' => '', 'LOGGED_IN_SALT' => '', 'NONCE_SALT' => '' ); $keys_salts = array( 'AUTH_KEY' => '', 'SECURE_AUTH_KEY' => '', 'LOGGED_IN_KEY' => '', 'NONCE_KEY' => '', 'AUTH_SALT' => '', 'SECURE_AUTH_SALT' => '', 'LOGGED_IN_SALT' => '', 'NONCE_SALT' => '' );
foreach ( $keys_salts as $c => $v ) { foreach ( $keys_salts as $c => $v ) {
if ( defined( $c ) ) if ( defined( $c ) )
unset( $keys_salts[ $c ] ); unset( $keys_salts[ $c ] );
} }
if ( ! empty( $keys_salts ) ) { if ( ! empty( $keys_salts ) ) {
$keys_salts_str = ''; $keys_salts_str = '';
$from_api = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' ); $from_api = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
@ -399,10 +400,13 @@ define('BLOG_ID_CURRENT_SITE', 1);</textarea>
</li> </li>
<?php <?php
if ( iis7_supports_permalinks() ) : if ( iis7_supports_permalinks() ) :
// IIS doesn't support RewriteBase, all your RewriteBase are belong to us
$iis_subdir_match = ltrim( $base, '/' ) . $subdir_match;
$iis_rewrite_base = ltrim( $base, '/' ) . $rewrite_base;
$iis_subdir_replacement = $subdomain_install ? '' : '{R:1}';
if ( $subdomain_install ) { $web_config_file = <<<EOF
$web_config_file = <?xml version="1.0" encoding="UTF-8"?>
'<?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<system.webServer> <system.webServer>
<rewrite> <rewrite>
@ -414,49 +418,14 @@ define('BLOG_ID_CURRENT_SITE', 1);</textarea>
if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) { if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) {
$web_config_file .= ' $web_config_file .= '
<rule name="WordPress Rule for Files" stopProcessing="true"> <rule name="WordPress Rule for Files" stopProcessing="true">
<match url="^files/(.+)" ignoreCase="false" /> <match url="^{$iis_subdir_match}files/(.+)" ignoreCase="false" />
<action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false" /> <action type="Rewrite" url="{$iis_rewrite_base}wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
</rule>'; </rule>';
} }
$web_config_file .= ' $web_config_file .= '
<rule name="WordPress Rule 2" stopProcessing="true"> <rule name="WordPress Rule 2" stopProcessing="true">
<match url="^" ignoreCase="false" /> <match url="^{$iis_subdir_match}wp-admin$" ignoreCase="false" />
<conditions logicalGrouping="MatchAny"> <action type="Redirect" url="{$iis_subdir_replacement}wp-admin/" redirectType="Permanent" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="WordPress Rule 3" stopProcessing="true">
<match url="." ignoreCase="false" />
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>';
} else {
$web_config_file =
'<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="WordPress Rule 1" stopProcessing="true">
<match url="^index\.php$" ignoreCase="false" />
<action type="None" />
</rule>';
if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) {
$web_config_file .= '
<rule name="WordPress Rule for Files" stopProcessing="true">
<match url="^files/(.+)" ignoreCase="false" />
<action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
</rule>';
}
$web_config_file .= '
<rule name="WordPress Rule 2" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?wp-admin$" ignoreCase="false" />
<action type="Redirect" url="{R:1}wp-admin/" redirectType="Permanent" />
</rule> </rule>
<rule name="WordPress Rule 3" stopProcessing="true"> <rule name="WordPress Rule 3" stopProcessing="true">
<match url="^" ignoreCase="false" /> <match url="^" ignoreCase="false" />
@ -467,12 +436,12 @@ define('BLOG_ID_CURRENT_SITE', 1);</textarea>
<action type="None" /> <action type="None" />
</rule> </rule>
<rule name="WordPress Rule 4" stopProcessing="true"> <rule name="WordPress Rule 4" stopProcessing="true">
<match url="^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*)" ignoreCase="false" /> <match url="^{$iis_subdir_match}(wp-(content|admin|includes).*)" ignoreCase="false" />
<action type="Rewrite" url="{R:1}" /> <action type="Rewrite" url="{$iis_rewrite_base}{R:1}" />
</rule> </rule>
<rule name="WordPress Rule 5" stopProcessing="true"> <rule name="WordPress Rule 5" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" /> <match url="^{$iis_subdir_match}([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
<action type="Rewrite" url="{R:2}" /> <action type="Rewrite" url="{$iis_rewrite_base}{R:2}" />
</rule> </rule>
<rule name="WordPress Rule 6" stopProcessing="true"> <rule name="WordPress Rule 6" stopProcessing="true">
<match url="." ignoreCase="false" /> <match url="." ignoreCase="false" />
@ -481,10 +450,11 @@ define('BLOG_ID_CURRENT_SITE', 1);</textarea>
</rules> </rules>
</rewrite> </rewrite>
</system.webServer> </system.webServer>
</configuration>'; </configuration>
} EOF;
?> ?>
<li><p><?php printf( __( 'Add the following to your <code>web.config</code> file in <code>%s</code>, replacing other WordPress rules:' ), ABSPATH ); ?></p> <li><p><?php printf( __( 'Add the following to your <code>web.config</code> file in <code>%s</code>, replacing other WordPress rules:' ), trailingslashit( str_replace( trailingslashit( $wp_siteurl_subdir ), '', ABSPATH ) ) ); ?></p>
<?php <?php
if ( ! $subdomain_install && WP_CONTENT_DIR != ABSPATH . 'wp-content' ) if ( ! $subdomain_install && WP_CONTENT_DIR != ABSPATH . 'wp-content' )
echo '<p><strong>' . __('Warning:') . ' ' . __( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</strong></p>'; echo '<p><strong>' . __('Warning:') . ' ' . __( 'Subdirectory networks may not be fully compatible with custom wp-content directories.' ) . '</strong></p>';
@ -495,27 +465,27 @@ define('BLOG_ID_CURRENT_SITE', 1);</textarea>
<?php else : // end iis7_supports_permalinks(). construct an htaccess file instead: <?php else : // end iis7_supports_permalinks(). construct an htaccess file instead:
$htaccess_file = 'RewriteEngine On $ms_files_rewriting = '';
RewriteBase ' . $base . '
RewriteRule ^index\.php$ - [L]' . "\n";
if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) { if ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) {
$htaccess_file .= "\n# uploaded files\nRewriteRule ^"; $ms_files_rewriting = "\n# uploaded files\nRewriteRule ^";
$htaccess_file .= ( $subdomain_install ? '' : '([_0-9a-zA-Z-]+/)?' ) . 'files/(.+) wp-includes/ms-files.php?file=$' . ( $subdomain_install ? 1 : 2 ) . ' [L]' . "\n"; $ms_files_rewriting .= $subdir_match . "files/(.+) {$rewrite_base}wp-includes/ms-files.php?file={$subdir_replacement_12} [L]" . "\n";
} }
if ( ! $subdomain_install ) $htaccess_file = <<<EOF
$htaccess_file .= "\n# add a trailing slash to /wp-admin\n" . 'RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]' . "\n"; RewriteEngine On
RewriteBase {$base}
RewriteRule ^index\.php$ - [L]
{$ms_files_rewriting}
# add a trailing slash to /wp-admin
RewriteRule ^{$subdir_match}wp-admin$ {$subdir_replacement_01}wp-admin/ [R=301,L]
$htaccess_file .= "\n" . 'RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]'; RewriteRule ^ - [L]
RewriteRule ^{$subdir_match}(wp-(content|admin|includes).*) {$rewrite_base}{$subdir_replacement_12} [L]
// @todo custom content dir. RewriteRule ^{$subdir_match}(.*\.php)$ {$rewrite_base}$subdir_replacement_12 [L]
if ( ! $subdomain_install ) RewriteRule . index.php [L]
$htaccess_file .= "\nRewriteRule ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]\nRewriteRule ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]"; EOF;
$htaccess_file .= "\nRewriteRule . index.php [L]";
?> ?>
<li><p><?php printf( __( 'Add the following to your <code>.htaccess</code> file in <code>%s</code>, replacing other WordPress rules:' ), ABSPATH ); ?></p> <li><p><?php printf( __( 'Add the following to your <code>.htaccess</code> file in <code>%s</code>, replacing other WordPress rules:' ), ABSPATH ); ?></p>
@ -537,14 +507,12 @@ RewriteRule ^ - [L]';
if ( $_POST ) { if ( $_POST ) {
$base = trailingslashit( stripslashes( dirname( dirname( $_SERVER['SCRIPT_NAME'] ) ) ) );
check_admin_referer( 'install-network-1' ); check_admin_referer( 'install-network-1' );
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
// create network tables // create network tables
install_network(); install_network();
$hostname = get_clean_basedomain(); $base = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
$subdomain_install = allow_subdomain_install() ? !empty( $_POST['subdomain_install'] ) : false; $subdomain_install = allow_subdomain_install() ? !empty( $_POST['subdomain_install'] ) : false;
if ( ! network_domain_check() ) { if ( ! network_domain_check() ) {
$result = populate_network( 1, get_clean_basedomain(), sanitize_email( $_POST['email'] ), stripslashes( $_POST['sitename'] ), $base, $subdomain_install ); $result = populate_network( 1, get_clean_basedomain(), sanitize_email( $_POST['email'] ), stripslashes( $_POST['sitename'] ), $base, $subdomain_install );

View File

@ -62,10 +62,10 @@ if ( isset($_REQUEST['action']) && 'add-site' == $_REQUEST['action'] ) {
if ( is_subdomain_install() ) { if ( is_subdomain_install() ) {
$newdomain = $domain . '.' . preg_replace( '|^www\.|', '', $current_site->domain ); $newdomain = $domain . '.' . preg_replace( '|^www\.|', '', $current_site->domain );
$path = $base; $path = $current_site->path;
} else { } else {
$newdomain = $current_site->domain; $newdomain = $current_site->domain;
$path = $base . $domain . '/'; $path = $current_site->path . $domain . '/';
} }
$password = 'N/A'; $password = 'N/A';

View File

@ -1729,7 +1729,7 @@ class WP_Rewrite {
<rewrite> <rewrite>
<rules>'; <rules>';
} }
if ( !is_multisite() ) {
$rules .= ' $rules .= '
<rule name="wordpress" patternSyntax="Wildcard"> <rule name="wordpress" patternSyntax="Wildcard">
<match url="*" /> <match url="*" />
@ -1739,73 +1739,7 @@ class WP_Rewrite {
</conditions> </conditions>
<action type="Rewrite" url="index.php" /> <action type="Rewrite" url="index.php" />
</rule>'; </rule>';
} else {
if (is_subdomain_install()) {
$rules .= '
<rule name="WordPress Rule 1" stopProcessing="true">
<match url="^index\.php$" ignoreCase="false" />
<action type="None" />
</rule>';
if ( get_site_option( 'ms_files_rewriting' ) ) {
$rules .= '
<rule name="WordPress Rule for Files" stopProcessing="true">
<match url="^files/(.+)" ignoreCase="false" />
<action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
</rule>';
}
$rules .= '
<rule name="WordPress Rule 2" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="WordPress Rule 3" stopProcessing="true">
<match url="." ignoreCase="false" />
<action type="Rewrite" url="index.php" />
</rule>';
} else {
$rules .= '
<rule name="WordPress Rule 1" stopProcessing="true">
<match url="^index\.php$" ignoreCase="false" />
<action type="None" />
</rule>';
if ( get_site_option( 'ms_files_rewriting' ) ) {
$rules .= '
<rule name="WordPress Rule for Files" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?files/(.+)" ignoreCase="false" />
<action type="Rewrite" url="wp-includes/ms-files.php?file={R:2}" appendQueryString="false" />
</rule>';
}
$rules .= '
<rule name="WordPress Rule 2" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?wp-admin$" ignoreCase="false" />
<action type="Redirect" url="{R:1}wp-admin/" redirectType="Permanent" />
</rule>
<rule name="WordPress Rule 3" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
</conditions>
<action type="None" />
</rule>
<rule name="WordPress Rule 4" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*)" ignoreCase="false" />
<action type="Rewrite" url="{R:1}" />
</rule>
<rule name="WordPress Rule 5" stopProcessing="true">
<match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
<action type="Rewrite" url="{R:2}" />
</rule>
<rule name="WordPress Rule 6" stopProcessing="true">
<match url="." ignoreCase="false" />
<action type="Rewrite" url="index.php" />
</rule>';
}
}
if ( $add_parent_tags ) { if ( $add_parent_tags ) {
$rules .= ' $rules .= '
</rules> </rules>