The following patch adds a "batch creation" functionality to multisite_manager. This means that you can choose to delay the site creation upon running a script. The advantage of this is that you can synchronize running this script with other actions, such as creating simlinks or setting permissions.

Comments

schuyler1d’s picture

Status: Needs review » Postponed (maintainer needs more info)

I'm not against incorporating your patch as-is (though, I'd have to actually test it first, a spot-check looks ok), but I'm more interested in your use-case.

If the purpose is really to give you an opportunity to run scripts before and/or after the installation, it seems an easier way that's also more drupaly would be to call module_invoke_all('before_multisite') and module_invoke_all('after_multisite').

Then you could make hooks in a separate module or theme that get called then. This would kill two birds with one stone, if this also solves this request: http://drupal.org/node/196492

My question to you is whether the delay of the site creation is essential for some other reason, or is it that you want to hook into the process? Even if the delay is important, it seems like this is a general feature that some enhancement on the cron side that would allow any node's creation to be delayed into a cron task.

davecormier’s picture

Here's the proof of concept php code for the permissions and roles. Still pretty preliminary, but you can see where it's going. The watchdog code simply grabs the watchdog info from ALL multisites and displays them in a single node on the 'master' site.

dbpr2.php supplies authentication and an array of database names.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head><title>UPEI.ca CMS Staging Environment</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<style type="text/css" media="all">@import "maintenance.css";</style>
<style type="text/css" media="all">@import "defaults.css";</style>
<style type="text/css" media="all">@import "system.css";</style></head>

<body>
<div style="float:right;"><img src="upei_n_m.gif" /></div>

<?php
                ////////////////////////////////
                // this is a draft of a new   //
                // version of Ryan Palmer's   //
                // proof of concept for admin //
                // tools for drupal multisite //
                ////////////////////////////////

        // dbpr2.php is scans the mysql server for existing databases and
        // outputs them to an array called $dbs
include ("dbpr2.php");

        // These are temporary hard coded variables, eventually I
        // imagine we'll turn these into an interface that allows
        // for other tables/fields to be accessed.
        // tbname = table name
        // finame = field name
$tbname = permission;
$tbname2 = role;
$tbname3 = filter_formats;
$finame1 = rid;
$finame2 = perm;
$finame3 = name;


        // This first part pulls out each db = database from $dbs
        // creates pushes all the tbname (in this case permission table)
        // into an array called $objects. The curly bracket started
        // here, goes to the end of the script.
foreach ($dbs as $db){
$objects = array();
$result = mysql_db_query("$db","select * from $tbname");
  while ($object = mysql_fetch_object($result)){
  array_push ($objects, $object);
}

if ($_GET[all_roles] == 'yes'){

        // This little piece just prints the name of the database to
        // the screen as a title
echo "<h2>". $db . " - multisite installation</h2>";


        // This section takes the field name rid from the array objects
        // created above and uses it to query a different table (role)
        // for the name associate with the RID from tbname (permission)
        // It them prints out all role names and permissions for each
        // database.
foreach ($objects as $data)
{
$rolename = mysql_query("select $finame3 from $tbname2 where $finame1 = '" . $data->$finame1 . "'");
$result1 = mysql_fetch_object($rolename);
echo "<i>". $result1->$finame3 . "</i><br>";
echo $data->$finame2 . "<br>";
}
}
}

        // Set access control permissions for a role name. Code is in
        // of several improvements including a check for existing role
        // a listing of available permissions and a check box for
        // choosing those permissions.


if(isset($_POST[role_to_set]) && isset($_POST[perms_to_set])){
echo "<br><strong>Role to set: ". @$_POST['role_to_set'] ." : ". @$_POST['perms_to_set'] ."</strong><br /><br />";
    echo "<table border='1'>";
 foreach($dbs as $site) {
 $perms_to_set = @$_POST['perms_to_set'];
 $role_to_set = @$_POST['role_to_set'];

// Get role ID from role name
 $query1 = mysql_query("SELECT $finame1 FROM ". $site .".$tbname2 WHERE $finame3 = '". $role_to_set ."'");
 $object1 = mysql_fetch_object($query1);

// Insert or Update?
 $query2 = mysql_query("SELECT * FROM ". $site .".$tbname WHERE $finame1 = '". $object1->$finame1 ."'");
 $object2 = mysql_fetch_object($query2);

 if ($object2) {
 $query = "UPDATE ". $site .".$tbname SET perm = '". $perms_to_set ."' WHERE $tbname.$finame1 = '". $object1->$finame1 ."' LIMIT 1";
   }

 else {

$query = "INSERT INTO ". $site .".$tbname VALUES ('". $object1->$finame1 ."', '". $perms_to_set ."', '')";
    }
$result = mysql_query($query) or die(mysql_error());

  echo '<tr><td><a href="/'. $site .'/admin/user/user">'. $site . "</a></td>";
  echo "<td>". $query ."</td></tr>\n";
    }
  echo "</table>";
     }

        // This resets the permissions across all sites to the code
        // given below. Needed first is a clear description of those
        // defaults and then a way of easily changing the defaults as
        // needs in a given project change.

if ($_GET[inputformats] == 'reset'){
echo "<br><strong>Reset all input formats</strong><br /><br />";
echo "<table border='1'>";

foreach($dbs as $site) {
echo '<tr><td><a href="/'. $site .'/admin/user/roles">'. $site ."</a></td><td>";

$queries[] = "DELETE FROM ". $site .".$tbname3";
$queries[] = "INSERT INTO ". $site .".$tbname3 VALUES ('1', 'Filtered HTML', ',1,2,', '1')";
$queries[] = "INSERT INTO ". $site .".$tbname3 VALUES ('2', 'PHP code', '', '0')";
$queries[] = "INSERT INTO ". $site .".$tbname3 VALUES ('3', 'Full HTML', ',2,', '1')";
$queries[] = "INSERT INTO ". $site .".$tbname3 VALUES ('4', 'Rich Editor', ',1,2,', '1')";

foreach ($queries as $query) {
   $result = mysql_query($query) or die('Query failed: ' . mysql_error());
   echo $query . "<br /><br />";
       }
  unset($queries);
  echo "</td></tr>";
      }
  echo "</table>";
 }


?>

        <!-- The Html here is calling two URLs which send [get] messages
        to the browser to activate the listing of all roles and the
        reset of all roles. Some javascript work to populate the existing
        fields into drop down menus could be very valuable.-->

<p><a href="getperms2.php?all_roles=yes">Get all roles from all sites</a></p>


<p><a href="getperms2.php?inputformats=reset">Reset the permissions as follows:</a></p>
<ul><li>Filtered HTML: Roles 1 & 2</li>
<li>PHP Code: Nobody</li>
<li>Full HTML: Role 2 (all authenticated)</li>
<li>Rich Editor: All users</li>
</ul>


<h2>Set perms for the whole system (be careful!!!)</h2>
<p><form name="set_perms" action="getperms2.php" method="post">
<label for="role_to_set">Role to set (name):</label>
<input type="text" name="role_to_set" size="25">
<label for="perms_to_set">Perms to set:</label> <input type="text" name="perms_to_set" size="25">
<input type="submit" value="Submit!"> <input type="reset">
</form></p>
schuyler1d’s picture

During installation, any watchdog messages go to the mainsite anyway (since watchdog switches the db back to the original anyway). Channeling these more explicitly might be something worth doing (presumably using the watchdog module hooks).

The rest seems like something that would go in a profile if I understand it correctly. But maybe the point is to perform actions globally AFTER installation? If so, then we're talking more about this kind of feature:
http://drupal.org/node/149337

I'm OK with discussing all these things, but we need to separate out what we're trying to do. You have a patch which allows for a delay in installation--is that something that is important as a feature--or is it a means to achieve something else? Either way, we need to flesh that out so we know what the code is achieving.

anarcat’s picture

The idea behind this patch is to allow the creation process to be run in a privileged user that could create apache vhosts, edit bind zone files, etc.

We are planning to provide extensions, hooks, probably, to provide this functionality, as we found the current implementation a bit lacking in flexibility.

Of course, using hooks here is also appropriate.

schuyler1d’s picture

ok, that's a use case I can get behind. To confirm how someone would run the script would be to chdir into the drupal home directory and run:

$ php ./PATH/TO/modules/multisite_manager/multisite_manager_batch_install.php

Should I apply this patch or is there a newer one with better hooks?

tatien’s picture

Yes, please apply it.

BTW anarcat and I are currently in the process of developing a "drupalfarm" project for Koumbit and we have chosen multisite_manager as our administration interface for the Drupals. We'll concentrate on other issues before publishing a patch for this feature, with better hooks.

schuyler1d’s picture

i've applied the patch (with some minor tweaks) in the 1.0 beta. What is your advice for where to run the admin script? Is there a way that people can run it without moving it to the drupal directory? Also, is there a good way for people to specify the bootstrapped database to use? how does it guess the right one in your environment (I presume the main db is in the /sites/default/ directory?)

schuyler1d’s picture

Status: Postponed (maintainer needs more info) » Fixed

also, what is the status of your other work?

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.