I wrote the following script to make the module install and update process a little more automatic. With a little bit of Drupal developer knowledge, the script can probably be extended to automatically download and apply module updates as they become available. I've found it very useful in lightening my Drupal admin load, I hope it helps other people too. The script can be easily modified to install and update themes instead of modules: just change the $drupalModulesPath variable to point to "themes" rather than "modules".

I've tested the script with Drupal 6. I don't know whether or not it will work with earlier versions. Feedback, comments, suggestions and criticisms are all welcome.


/*
 * drupal_module_install.php v1.0
 *
 * Installs a Drupal module to all sites, or upgrades a module in situ.  Don't forget
 * to run update.php after module upgrade.  
 *
 * To install modules to a specific site, change the $installModulesForSite variable
 * appropriately.
 */

/*
 * Configuration
 */

// The root directory of your Drupal installation
$drupalRoot = "/var/www/drupal";

// Which site to install the module for.  Defaults to "all"
// Can be pointed at a specific site if you prefer.
$installModulesForSite = "all";


// The user that owns the Drupal files.  Usually httpd, www-data, or similar.
$drupalFilesOwner = "www-data";

// The group that owns the Drupal files.  Usually the same as the username.
$drupalFilesGroup = "www-data";

/*
 * The script
 */

// Process arguments passed in on the command-line
// ? and h options display help information.
// u option puts the script into upgrade mode (default is install)
$options = getopt("?hu");
if ($options["h"] || $options["?"] || $argc < 2) {
  usage();
}
 
install($argv[$argc - 1], array_key_exists("u", $options));
 
function install($url, $update = false) {
  // Get the useful bits of information out of the URL, like the tar file and the module name.
  $file = parse_url($url, PHP_URL_PATH);
  strtok($file, "/");
  strtok("/");
  $file = strtok("/");
  $module = strtok($file, "-");
  
  if ($update) {
    echo "Updating $module\n";
  } else {
    echo "Installing $module\n";
  }
 
  // Switch to a temporary directory and download the module
  chdir("/tmp");
  echo "wget $url\n";
  exec("wget $url");

  // Extract the module
  echo "tar -zxf $file\n";
  exec("tar -zxf $file");

  $drupalModulesPath = "$drupalRoot/sites/$installModulesForSite/modules";

  // Copy (on update) or move (on install) the directory to the modules 
  // directory in Drupal.  mv fails if the files already exist.
  if ($update) {
    echo "cp -R $module/* $drupalModulesPath/$module/\n";
    exec("cp -R $module/* $drupalModulesPath/$module/");
  } else {
    echo "mv $module $drupalModulesPath/modules\n";
    exec("mv $module $drupalModulesPath/modules");
  }

  // Update the permissions on the new files to match the rest of the Drupal site
  echo "chown -R $drupalFilesOwner:$drupalFilesGroup $drupalModulesPath/$module\n";
  exec("chown -R $drupalFilesOwner:$drupalFilesGroup $drupalModulesPath/$module");

  // Remove the tar file
  echo "rm $file\n";
  exec("rm $file");

  // Clean up the extracted module files if they were copied rather than moved.
  if ($update) {
    echo "rm -Rf $module\n";
    exec("rm -Rf $module");
  }
}
 
function usage() {
  echo "drupal_module_install [-u] url\n\n";
  echo "Options:\n\n";
  echo "    -u        Perform an upgrade of the module rather than a fresh install\n";
}
 

Comments

tonychung’s picture

Thanks for writing this script.

Within the install function, I had to declare the scope of the global $drupalRoot, $installModulesForSite, $drupalFilesOwner, $drupalFilesGroup variables.

The next most logical step would be to find some way to parameterize a variety of module locations and download sources, then loop upgrade/install and log the results. For my personal use I'll probably code a crude web form and load the results through AJAX.

alastair’s picture

Yes, that would be required in some PHP configurations - I guess not in either of mine. It's been a while since I did any PHP "for real" - I mostly just hack together quick scripts like this with it these days - so sorry for missing that.

Anonymous’s picture

Hey - I would like to use this script .. just not sure where to put it. Do I just save to as a php file and put it in the root or must this code be added to a file?

Stomper’s picture

This should be included in Drupal core. By now, Drupal should offer one-click module and core upgrades. It'd make the entire process effortless. What's stopping it from being added as a much needed UX feature?