drupal's domain access and sites in subfolders

Domain Access is a module which allows you to simulate Drupal's internal multi-site functionality; it is easy to set up, and even easier to use. This is (by far) the simplest way of sharing content (and users) between multiple sites. One of DA's downfalls is that it does not work with subsites in subfolders, meaning the structure of site.com and site.com/subsite is not supported. Due to very specific client needs, my project required just that - subsites in subfolders. "Not supported" was not an acceptable answer, so... here is my solution:

Start off by enabling Domain Access (& other related modules that come in the package) and setting up a new domain under Site Building -> Domains - set the new domain up as a subdomain, so you end up with site.com and subsite.site.com. You should now create the appropriate subsite.site.com domain record in your vhosts file, or otherwise create the subdomain to point to your main (site.com) Drupal installation.

The next step is adding this little bit of magic at the top of your index.php file. Yes, we're modifying a core file, but it's not too bad:

//add folders in which the subsites reside to this array $sites = array( 'subsite', ); $request = explode('/', trim($_SERVER['REQUEST_URI'], '/')); if (sizeof($request) && preg_match('/^'.implode('|', $sites).'$/i', $request[0], $matches)) { //set the appropriate HTTP_HOST to trick Domain Access $site = $matches[0]; $_SERVER['ORIGINAL_HTTP_HOST'] = $_SERVER['HTTP_HOST']; $_SERVER['HTTP_HOST'] = $site.'.'.$_SERVER['HTTP_HOST']; //rebuild the Q if (!empty($_GET['q'])) { $q = implode('/', $request); if(($pos = strpos($q, '?')) !== FALSE) { $q = substr($q, 0, $pos); } $size = strlen($site); $_GET['q'] = ltrim(substr($q, $size), '/'); $HTTP_GET_VARS['q'] = $q; } //used to set the correct $base_url in settings.php global $da_site; $da_site = $site; }

(On my project I actually have this in an external file and simply added an include in index.php.)

Now we need to update settings.php in your sites/default folder:

Find the line which contains the default $base_path code and replace it with this:

global $da_site; if ($da_site) { $base_url = 'http://'.$_SERVER['ORIGINAL_HTTP_HOST'].'/'.$da_site; }

Also uncomment the $cookie_domain variable and set it to your site's root: $cookie_domain = 'site.com';

... this will share sessions between your main site and subsites, so when a user logs in to one site, they're logged in to all sites. If you skip this step, users will not be able to log in on your subsites.

Don't forget to add the appropriate configuration to settings.php for the Domain Access module! See DA's readme/install files.

The last step is updating your .htaccess file.

Add this:

# DomainAccess-related # Removes the site prefix to ensure file paths still work RewriteRule ^subsite(.*) /$1 [L,QSA]

Right above:

# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.

That's it! Your Drupal site will now be tricked into thinking it's running on the subsite.site.com subdomain whenever you access site.com/subsite.

NOTE: This functionality has undergone very limited testing, so it's entirely possible that there may be issues. Please post your results!

comments powered by Disqus