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.

2 s
2

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:

network site list

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.)

adminer edit wp_options

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:

adminer edit 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 |
+---------+--------------------+---------------------+---------------------+

network site list updated

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.

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *