We are running several sub-domain sites on a WordPress Multisite environment and want to switch the primary site from the root to a sub-domain like so:
Current site is example.com
with ID 1
(cannot rename because field is set and uneditable)
New site is new.example.com
with ID 15
(tried to rename to example.com
)
I followed some instructions for switching that involved renaming the sites and updating the wp-config.php
file to give the new ID of 15 for the SITE_ID_CURRENT_SITE
and Blog_ID_CURRENT_SITE
. The result was the main site did not change and the admin got mucked up.
Is there a straight forward way to switch the main site out and replace it with the sub-domain site content without importing posts/pages and plugins?
UPDATE:
Thanks for giving these tips. My conclusion with what I’ve seen in the database, read, and get from you is that the new subdomain site to replace the main site needs to have the base table names and ID of 1, updated paths etc. My only worry is that after switching these the network admin will have a problem — so I basically need to compare the base tables (wp_options etc) to the equivalent (wp_x_options etc) to see if there is anything unique related to the network admin in those base tables.
Four years old and no answer? So here we go…-
Let’s take the following network setup as example (I’m using WP-CLI’s site list command):
$ wp site list
+---------+--------------------+---------------------+---------------------+
| blog_id | url | last_updated | registered |
+---------+--------------------+---------------------+---------------------+
| 1 | http://wp.tmp/ | 2016-08-04 08:39:35 | 2016-07-22 09:25:42 |
| 2 | http://foo.wp.tmp/ | 2016-07-22 09:28:16 | 2016-07-22 09:28:16 |
+---------+--------------------+---------------------+---------------------+
The network site list would look like this:

We want to use the site with ID 2
as the new root site with the URL http://wp.tmp/
. This is actually the same problem as described in the question just with some other values for the ID and the URLs.
The multisite relevant part of the wp-config.php
looks probably like this:
const MULTISITE = TRUE;
const DOMAIN_CURRENT_SITE = 'wp.tmp';
const PATH_CURRENT_SITE = "https://wordpress.stackexchange.com/";
const SITE_ID_CURRENT_SITE = 1;
const BLOG_ID_CURRENT_SITE = 1;
const SUBDOMAIN_INSTALL = TRUE;
Updating database site settings
WordPress uses the tables wp_*_option
and wp_blogs
to find the matching blog for a given request URL and to build proper permalinks for this blog. So we have to change the values in the following three tables (for this example):
- In
wp_options
the keys home
and siteurl
- In
wp_2_options
the keys home
and siteurl
(in your case this would be wp_15_options
)
- In
wp_blogs
the column domain
for both sites with ID 1
and 2
(respectively 15
)
I’m using Adminer for this, but any other DB management tool (PhpMyAdmin) does the job as well. (The screenshots shows the GUI in German language but I guess the idea is clear.)

In wp_options
(the options table for site ID 1
) I changed the values of both keys home
and siteurl
from http://wp.tmp
to http://foo.wp.tmp
. (The screenshot above shows the state before the update.)
I did exactly the same with the table wp_2_options
but here I changed the value from http://foo.wp.tmp
to http://wp.tmp
.
Next step is to update the table wp_blogs
:

(Again, the screenshot shows the table before I made any change.) Here you simply switch the values from both sites in the domain
column:
wp.tmp
becomes foo.wp.tmp
and
foo.wp.tmp
becomes wp.tmp
Now you have to update the wp-config.php
to deal correctly with the new settings data:
const MULTISITE = TRUE;
const DOMAIN_CURRENT_SITE = 'wp.tmp';
const PATH_CURRENT_SITE = "https://wordpress.stackexchange.com/";
const SITE_ID_CURRENT_SITE = 1;
const BLOG_ID_CURRENT_SITE = 2; // This is the new root site ID
const SUBDOMAIN_INSTALL = TRUE;
At this point you have again a working WordPress multisite but with a new root site:
$ wp site list
+---------+--------------------+---------------------+---------------------+
| blog_id | url | last_updated | registered |
+---------+--------------------+---------------------+---------------------+
| 1 | http://foo.wp.tmp/ | 2016-08-04 08:39:35 | 2016-07-22 09:25:42 |
| 2 | http://wp.tmp/ | 2016-07-22 09:28:16 | 2016-07-22 09:28:16 |
+---------+--------------------+---------------------+---------------------+

Remember: during this process, your site will be not available and requests will end up in some nasty errors so you might want to arrange a 503 Service Unavailable
response in front of your WordPress installation. This could be done using .htaccess
.
Updating database content
Now comes the tricky part. At the moment, all URLs in the content tables are still pointing to the resources of the old sites. But replacing them is not that easy: Replacing every http://foo.wp.tmp
with http://wp.tmp
in the first step and every http://wp.tmp
with http://foo.wp.tmp
in the next step will end up in having all former URLs pointing to site ID 1 (http://foo.wp.tmp
).
The best way would be to insert an intermediate step:
- Search for
http://foo.wp.tmp
and replace it with a preferably unique slug: http://3a4b522a.wp.tmp
- Search for
http://wp.tmp
and replace it with http://foo.wp.tmp
- Search for
http://3a4b522a.wp.tmp
and replace it with http://wp.tmp
All these search and replace commands should ignore the three tables (*_options
*_blogs
) we updated before, otherwise they would break the configuration. You might also have a manual look for URLs in wp_*_options
table outside of the home
and siteurl
keys.
I would suggest to use WP-CLI’s search-replace command for this as it can deal with serialized data and has no limitations that HTTP might have.