8

I've set up a multi-site Drupal installation. The main site is example.com and we also have a.example.com and b.example.com.

I own example.com, and I rent a.example.com out to Person A, and b.example.com out to Person B. They pay their site rent using the UberCart role-purchase feature on my site. I need a way to set up my site so that Person A and B can log into example.com and pay their site rent, and have the upgraded role transfer over to a.example.com and b.example.com as well, automatically so that after a month if Ubercart downgrades their role I don't have to go in and manually unassign them.

Things I've tried:

  1. Shared users table. This doesn't work because I don't want Person A to be able to see people who have signed up for b.example.com and a shared user site means everyone can see everything.

  2. Domain Access. This works ok but is really shaky, and I'm planning on moving up to z.example.com and onward in the future, so unless there's a way to keep things more separate than I was able to, I don't think this is feasible. For example, if each site has an 'about us' page then I would see 26 "About Us" pages from my uid=1 account. Additionally, I didn't see any way of separating the UberCart module as much as I would like. Ubercart Marketplace is a no-go because I'm not taking any commission like it was designed to do, and UC_Domain hasn't been upgraded to drupal 7 yet.

  3. Account Sync. This seemed like the closest, but the plugin appears broken, I get tons of XML-RPC errors when I try it, and generally it doesn't work as described, and seems to only sync the first account before breaking. Google searching the errors brings back nothing apart from warnings that XMLRPC is potentially dangerous.

  4. Bakery. This seems great but it doesn't share roles across subsites unfortunately. I've been trying to add that in, but before I spent the time I wanted to see if there's some other way that I can go about this

If anybody needs clarification on anything let me know, I really want to get this solved and can't find anything online.

2

4 Answers 4

2

Hope the question is for Drupal 7 or lesser. If it's for Drupal 8, the solution is close to impossible. And for future Drupal versions, as per the current plan for Drupal 9, multi-site option itself shall not be available, which mean sharing user role using Drupal's default options, is clearly impossible.

In Drupal 7 or lower, in the multi-site setup, it's very easily possible to configure each site to use different databases for their contents, and share the same table (from same database) just for users, roles, sessions, etc. If you don't want to share users, but want to share only roles, even that is possible. For this, the settings.php for site A and site B has to be as below:

settings.php for Site A:

/*
 * Database Settings for 'Site A'
 */
$databases['default']['default'] = array (
    'database' => 'site_a_db_name',    // Specify Site A's main database name
    'username' => 'site_a_db_username',
    'password' => 'site_a_db_password',
    'prefix' => array(
        'default' => 'site_a_prefix_',    // Prefix for all tables in Site A's main database (specified above), other than for the tables specified below
        'role' => 'shared_db_name.shared_prefix_',              // Shared database name and prefix for the 'role' table
        'users' => 'shared_db_name.shared_prefix_',             // Shared database name and prefix for the 'users' table
        'authmap' => 'shared_db_name.shared_prefix_',           // Shared database name and prefix for the 'authmap' table
        'sessions' => 'shared_db_name.shared_prefix_',          // Shared database name and prefix for the 'sessions' table
        'profile_fields' => 'shared_db_name.shared_prefix_',    // Shared database name and prefix for the 'profile_fields' table
        'profile_values' => 'shared_db_name.shared_prefix_',    // Shared database name and prefix for the 'profile_values' table
    ),
    'host' => 'localhost',
    'port' => '3306',
    'driver' => 'mysql',
    'collation' => 'utf8mb4_general_ci',
);

settings.php for Site B:

/*
 * Database Settings for 'Site B'
 */
$databases['default']['default'] = array (
    'database' => 'site_b_db_name',    // Specify Site B's main database name
    'username' => 'site_b_db_username',
    'password' => 'site_b_db_password',
    'prefix' => array(
        'default' => 'site_b_prefix_',    // Prefix for all tables in Site B's main database (specified above), other than for the tables specified below
        'role' => 'shared_db_name.shared_prefix_',              // Shared database name and prefix for the 'role' table
        'users' => 'shared_db_name.shared_prefix_',             // Shared database name and prefix for the 'users' table
        'authmap' => 'shared_db_name.shared_prefix_',           // Shared database name and prefix for the 'authmap' table
        'sessions' => 'shared_db_name.shared_prefix_',          // Shared database name and prefix for the 'sessions' table
        'profile_fields' => 'shared_db_name.shared_prefix_',    // Shared database name and prefix for the 'profile_fields' table
        'profile_values' => 'shared_db_name.shared_prefix_',    // Shared database name and prefix for the 'profile_values' table
    ),
    'host' => 'localhost',
    'port' => '3306',
    'driver' => 'mysql',
    'collation' => 'utf8mb4_general_ci',
);

As shown in the above code, under 'prefix' array, we can specify separate database and prefix for each different table used in the site. Other than those tables exclusively specified in the 'prefix' array, for all other tables, the prefix specified as 'default' shall be used.

In Drupal 8, user/role/session sharing is not as easy as in Drupal 7, because in Drupal 8, many of the informations, including the user roles, are part of a shared table (that shared table is meant for storing many different variable values, and roles are just part of that).

0

You could use a secondary database (or a specific table) for all your sites where you manage each site's user roles. You would then need to:

  • Define a cron job for each site (a-z).example.com which looks up the database and updates the roles of the users on the site
  • Update the database when people buy on example.com
  • Trigger cron from example.com after the UberCart transaction is completed

The other way to do that would be to expose a POST (REST) web service endpoint on the sub-sites which will trigger a function to update the roles based on the data submitted. You then call that endpoint after the UberCart transaction.

In both cases, I'm assuming there's a hook you can use to do things after a UberCart transaction (or maybe something like Rules).

0

Easiest way if you do not want to develop so much is change a bit about sharing tables:

https://www.drupal.org/node/22267

But if you only want to share roles just sare the roles table.

This is the exaple you can use:

$db_prefix = array(
    "default" => "slave1_", // the prefix for tables that are not shared.
    "role" => "master_",
); 
0

Create an additional database. Can be an own drupal instance or a php framework like yii, where you can model the database by your own. There you manage the account data. From there you sync the roles via a cronjob (e.g. a REST call). After you have loaded the account credential data, you use this two Drupal API functions to update the account credentials:

This approach will do the job, if you are not just looking for a finished module, which does the job for you. Then you get you better a coder, who helps you out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.