t("Drupal sites"));
}
/**
* Implentation of hook_provision_configure()
* @TODO: PROPER profile support
function provision_drupal_provision_configure() {
$profiles = file_scan_directory('./profiles', '\.profile$', array('.', '..', 'CVS'), 0, TRUE, 'name', 0);
// Don't need to choose profile if only one available.
if (sizeof($profiles) == 1) {
$profile = array_pop($profiles);
$form['default_profile'] = array('#type' => 'value', '#value' => $profile->name);
}
elseif (sizeof($profiles) > 1) {
foreach ($profiles as $profile) {
if ($_POST['profile'] == $profile->name) {
$options[$profile->name] = $profile->name;
}
}
$form['provision_default_profile'] = array(
'#type' => 'radios',
'#title' => t('Default install profile'),
'#description' => t('New sites will be created with the following install profile'),
'#options' => $options,
'#default_value' => variable_get('provision_default_profile', 'default'),
);
}
return $form;
}
//*/
/**
* Implementation of hook_provision_templates
*/
function provision_drupal_provision_templates() {
// settings template
}
/**
* @} End "ingroup provisionui"
*/
/**
* Test to see if the site settings.php exists
*
* @param url
* The url of the site to check
* @return
* If the file exists, return TRUE, else return FALSE.
*/
function _provision_drupal_site_exists($url) {
return file_exists("sites/$url/settings.php");
}
function _provision_drupal_site_installed($url) {
if (_provision_drupal_site_exists($url)) {
if ($data = provision_load_site_data($url)) {
return isset($data['site_installed']) ? $data['site_installed'] : FALSE;
}
}
return false;
}
/**
* Implentation of hook_provision_backup()
*/
function provision_drupal_provision_backup($url, $data) {
// Adds the site directory into the backup file
provision_log("backup", "Adding sites directory to $data[backup_file].gz");
$result = provision_shell_exec("cd %s; tar -rf %s * ", "sites/$url", $data['backup_file']);
if (!$result) {
provision_log("error", "Could not back up sites directory for drupal");
provision_set_error(PROVISION_FRAMEWORK_ERROR);
}
}
/**
* The default template to use while generating config files.
*
* @return
* The default template for the config file
*/
function _provision_drupal_default_template() {
return file_get_contents(drupal_get_path('module', 'provision_drupal') . '/provision_drupal_settings.tpl.php');
}
/**
* Generate a settings file for the site.
*
* @param url
* The url of the site being invoked.
* @param data
* A reference to the associated array containing the data for the site. This needs to be a reference,
* because the modules might provide additional information about the site.
*/
function _provision_drupal_create_settings_file($url, &$data) {
provision_log('notice', t("Generate settings.php file"));
if (provision_path("exists", "sites/$url/settings.php")) {
provision_path("chmod", "sites/$url/settings.php", 0750,
t('Changed permissions of settings.php to @confirm'),
t('Could not change permissions of settings.php to @confirm'));
}
$fp = fopen("sites/$url/settings.php", "w");
$text = variable_get('provision_drupal_settings_template', _provision_drupal_default_template());
fwrite($fp, " 0750,
"sites/$url/files" => 02750,
"sites/$url/files/tmp" => 02770,
"sites/$url/files/images" => 02770,
"sites/$url/files/pictures" => 02770,
"sites/$url/themes" => 02750,
"sites/$url/modules" => 02750,
);
foreach ($paths as $path => $perm) {
if (!is_dir($path)) {
provision_path("mkdir", $path, true,
t("Created @path
"),
t("Could not create @path
"),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
}
provision_path("chown", $path, PROVISION_SCRIPT_USER,
t("Changed ownership of @path
"),
t("Could not change ownership @path
"),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
provision_path("chgrp", $path, PROVISION_WEB_GROUP,
t("Changed group ownership of @path
"),
t("Could not change group ownership @path
"));
provision_path("chmod", $path, $perm,
t("Changed permissions of @path
to @confirm"),
t("Could not change permissions @path
to @confirm"),
PROVISION_PERM_ERROR | PROVISION_INSTALL_ERROR );
}
}
/**
* Switch the active database to the newly created database
*
* This function tricks Drupal into thinking that it's running on an uninstalled site,
* so that it can cleanly install the database schema. It also handles switching back to the
* main provisioning site.
*/
function _provision_drupal_switch_active_site($url = null) {
static $backups;
if ($url) {
/* Pretend to be the site being installed */
// Fake the necessary HTTP headers that Drupal needs:
$drupal_base_url = parse_url($url);
$_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
$_SERVER['PHP_SELF'] = $drupal_base_url['path'].'/index.php';
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
$_SERVER['REMOTE_ADDR'] = NULL;
$_SERVER['REQUEST_METHOD'] = NULL;
/**
* This code is sourced from bootstrap.inc. I am trying to avoid patching core, but it might
* be smarter to make a small patch to allow core to re-initialize itself more easily
*/
// Export the following settings.php variables to the global namespace
global $base_url, $base_path, $base_root;
global $cookie_domain, $conf, $profile, $profile, $db_prefix;
# This is just for backup, to be able to restore to the old DRUSH system.
$backups = compact("active_db", "base_url", "base_path", "db_prefix", "cookie_domain", "conf", "profile");
include_once $_SERVER['DOCUMENT_ROOT'] .'sites/' . $url . '/settings.php';
// Create base URL
$base_root = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
$base_url = $base_root .= '://'. preg_replace('/[^a-z0-9-:._]/i', '', $_SERVER['HTTP_HOST']);
if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
$base_path = "/$dir";
$base_url .= $base_path;
$base_path .= '/';
}
else {
$base_path = '/';
}
provision_set_active_db($db_url);
}
else {
/**
* Restore everything to the way it was before we switched sites.
*/
// Fake the necessary HTTP headers that Drupal needs:
$drupal_base_url = parse_url(DRUSH_URI);
$_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
$_SERVER['PHP_SELF'] = $drupal_base_url['path'].'/index.php';
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
$_SERVER['REMOTE_ADDR'] = NULL;
$_SERVER['REQUEST_METHOD'] = NULL;
global $base_url, $base_path, $base_root;
// Export the following settings.php variables to the global namespace
global $db_prefix, $cookie_domain, $conf, $profile;
# This is just for backup, to be able to restore to the old DRUSH system.
extract($backups, EXTR_OVERWRITE);
provision_set_active_db();
}
}
function provision_drupal_provision_post_restore($url, $data) {
_provision_drupal_create_settings_file($url, $data);
}
function provision_drupal_provision_restore($url, $data) {
$old = PROVISION_SITES_PATH . "/$url.restore";
$new = PROVISION_SITES_PATH . "/$url";
provision_path("switch_paths", $old, $new ,
t('Swapping out the @path and @confirm directories was successful.'),
t('Swapping the @path and @confirm directories has failed.'),
PROVISION_PERM_ERROR);
// make sure it has the latest site data available
provision_save_site_data($url, $data);
}
// Luckily this is reversable =)
function provision_drupal_provision_restore_rollback($url, $data) {
provision_drupal_provision_restore($url, $data);
}
/**
* Force drupal to load the modules it expects to find on an uninstalled site
*/
function _provision_drupal_force_load_modules($url = null) {
static $backup_list;
if ($url) {
$backup_list = module_list();
require_once './modules/system/system.install';
require_once './includes/file.inc';
require_once './includes/install.inc';
// Load module basics (needed for hook invokes).
include_once './includes/module.inc';
$module_list['system']['filename'] = 'modules/system/system.module';
$module_list['filter']['filename'] = 'modules/filter/filter.module';
module_list(TRUE, FALSE, FALSE, $module_list);
drupal_load('module', 'system');
drupal_load('module', 'filter');
#should i load all the other modules? i don't know .=\
}
else {
module_list(TRUE, FALSE, FALSE, $backup_list);
}
}
/**
* Install the drupal schema and install profile
*/
function _provision_drupal_install_schema($profile, $language = 'en') {
include_once('includes/locale.inc');
$GLOBALS['profile'] = $profile;
$GLOBALS['install_locale'] = $language;
provision_log("install", t("Installing Drupal schema"));
// Load the profile.
require_once "./profiles/$profile/$profile.profile";
$requirements = drupal_check_profile($profile);
$severity = drupal_requirements_severity($requirements);
// If there are issues, report them.
if ($severity == REQUIREMENT_ERROR) {
foreach ($requirements as $requirement) {
if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) {
drupal_set_message($requirement['description'] .' ('. st('Currently using !item !version', array('!item' => $requirement['title'], '!version' => $requirement['value'])) .')', 'error');
}
}
return false;
}
// Verify existence of all required modules.
$modules = drupal_verify_profile($profile, $language);
if (!$modules) {
provision_set_error(PROVISION_FRAMEWORK_ERROR);
return false;
}
// Perform actual installation defined in the profile.
drupal_install_profile($profile, $modules);
// Show profile finalization info.
$function = $profile .'_profile_final';
if (function_exists($function)) {
// More steps required
$profile_message = $function();
}
}
/**
* implementation of provision_verify
*/
function provision_drupal_provision_verify($url, &$data) {
provision_path("writable", "sites", true, t("Drupal sites directory is writable by the provisioning script"),
t("Drupal sites directory is not writable by the provisioning script"), PROVISION_PERM_ERROR);
$exists = _provision_create_dir(PROVISION_DRUSHRC_PATH, t('Drush configuration path'), 0700);
$data['modules'] = _provision_drupal_get_cvs_versions(module_rebuild_cache());
// Find theme engines
$data['engines'] = drupal_system_listing('\.engine$', 'themes/engines');
$data['profiles'] = _provision_find_profiles();
$data['themes'] = system_theme_data();
$sites = provision_drupal_find_sites();
$data['sites'] = array_keys($sites); // return list of hosted sites. used to determine whether or not to import.
}
/**
* Find available profiles on this platform.
*/
function _provision_find_profiles() {
include_once('includes/install.inc');
$profiles = file_scan_directory('./profiles', '\.profile$', array('.', '..', 'CVS', '.svn'), 0, TRUE, 'name', 0);
foreach ($profiles as $key => $profile) {
require_once($profile->filename);
$func = $profile->name . "_profile_details";
if (function_exists($func)) {
$profile->info = $func();
}
// Find languages available
$languages = array_keys(file_scan_directory('./profiles/' . $key, '\.po$', array('.', '..', 'CVS'), 0, FALSE, 'name'));
array_unshift($languages, 'en');
$profile->info['languages'] = $languages;
$return[$key] = $profile;
}
return $return;
}
/**
* Remove any directories for the site in sites
* This can't be rolled back. so won't even try.
*/
function provision_drupal_provision_delete($url, $data) {
return _provision_recursive_delete("sites/$url");
}
function provision_drupal_find_sites() {
$sitephp = file_scan_directory('./sites', 'settings\.php$', array('.', '..', 'CVS', '.svn'), 0, TRUE, 'filename', 0);
foreach ($sitephp as $file => $info) {
$path = explode("/", $file);
array_pop($path);
$sites[array_pop($path)] = $file;
}
return $sites;
}
function _provision_drupal_get_cvs_versions($files) {
foreach ($files as $modulename => $file) {
$project = array();
$project['filename'] = $file->filename;
$project['name'] = $file->name;
if (empty($project['project'])) {
$project['project'] = cvs_deploy_get_project_name($project);
}
_cvs_deploy_version_alter($file->info['version'], $project);
$name = ($project['project']) ? $project['project'] : $modulename;
$files[$name] = $file;
}
return $files;
}
function provision_drupal_provision_import($url, &$data) {
$sites = provision_drupal_find_sites();
foreach ($sites as $site => $file) {
if ($site != 'default') {
$info = _provision_drupal_import_site($site);
if ($info['site_installed']) {
provision_log("notice", "Returning information for $site");
$data['sites'][$site] = $info;
}
}
}
//Just make sure our ini settings and the like aren't wiped out.
include(conf_path() . "/settings.php");
}
function _provision_drupal_import_site($url) {
if (!($data = provision_get_site_data($url))) {
$data = array(); // initialize site data to empty array
}
include("sites/$url/settings.php");
if ($parts = @parse_url($db_url)) {
$data['site_db_type'] = $parts['scheme'];
$data['site_db_user'] = $parts['user'];
$data['site_db_host'] = $parts['host'];
$data['site_db_passwd'] = $parts['pass'];
$data['site_db_name'] = substr($parts['path'], 1);
/**
* We need to be running AS the site to be able to see what profile it is installed with.
*
* This information is no longer stored in settings.php
*/
_provision_drupal_switch_active_site($url);
$data['site_profile'] = variable_get('install_profile', 'default');
_provision_drupal_switch_active_site();
$data['site_installed'] = TRUE;
}
provision_save_site_data($url, $data);
return $data;
}