= 7) { $options['db_type'] = ($options['db_type'] == 'mysqli') ? 'mysql' : $options['db_type']; } $options['extra_config'] = "# Extra configuration from modules:\n"; $options['extra_config'] .= join("\n", drush_command_invoke_all('provision_drupal_config', $url, $options)); drush_log(dt("Generate settings.php file")); if (provision_path("exists", "sites/$url/settings.php")) { provision_path("chmod", "sites/$url/settings.php", 0640, dt('Changed permissions of settings.php to @confirm'), dt('Could not change permissions of settings.php to @confirm')); } $fp = fopen("sites/$url/settings.php", "w"); $text = _provision_drupal_default_template(); fwrite($fp, " 0755, "sites/$url/files" => 02770, "sites/$url/files/tmp" => 02770, "sites/$url/files/images" => 02770, "sites/$url/files/pictures" => 02770, "sites/$url/themes" => 0755, "sites/$url/modules" => 0755, "sites/$url/libraries" => 0755, # http://drupal.org/node/496240 ); $grps = array( "sites/$url/files", "sites/$url/files/tmp", "sites/$url/files/images", "sites/$url/files/pictures", ); foreach ($paths as $path => $perm) { if (!is_dir($path)) { provision_path("mkdir", $path, TRUE, dt("Created @path"), dt("Could not create @path"), 'DRUSH_PERM_ERROR'); } provision_path("chmod_recursive", $path, $perm, dt("Changed permissions of @path to @confirm"), dt("Could not change permissions @path to @confirm") ); } foreach ($grps as $path) { provision_path("chown_recursive", $path, drush_get_option('script_user'), dt("Changed ownership of @path"), dt("Could not change ownership @path"), 'DRUSH_PERM_ERROR' ); provision_path("chgrp_recursive", $path, drush_get_option('web_group'), dt("Changed group ownership of @path"), dt("Could not change group ownership @path")); } } /** * Runs an external script to reload all the various drupal caches */ function _provision_drupal_rebuild_caches($url = NULL) { if (PROVISION_CONTEXT_SITE) { drush_include_engine('drupal', 'clear'); } } /** * Find available profiles on this platform. */ function _provision_find_profiles() { include_once('includes/install.inc'); if (!$dir = opendir("./profiles")) { drush_log(dt("Cannot find profiles directory"), 'error'); return FALSE; } while (FALSE !== ($name = readdir($dir))) { $languages = array(); $file = "./profiles/$name/$name.profile"; if ($name == '..' || $name == '.' || !file_exists($file)) { continue; } $profile = new stdClass(); $profile->name = $name; $profile->filename = $file; _provision_cvs_deploy($profile); require_once($profile->filename); $func = $profile->name . "_profile_details"; if (function_exists($func)) { $profile->info = $func(); } $languages['en'] = 1; // Find languages available $files = array_keys(drush_scan_directory('./profiles/' . $name . '/translations', '/\.po$/', array('.', '..', 'CVS'), 0, FALSE, 'filepath')); $files = array_merge($files, array_keys(drush_scan_directory('./profiles/' . $name , '/\.po$/', array('.', '..', 'CVS'), 0, FALSE, 'filepath'))); if (is_array($files)) { foreach ($files as $file) { if (preg_match('!(/|\.)([^\./]+)\.po$!', $file, $langcode)) { $languages[$langcode[2]] = 1; // use the language name as an index to weed out duplicates } } } $profile->info['languages'] = array_keys($languages); $return[$name] = $profile; drush_log(dt('Found install profile %name', array('%name' => $name))); } return $return; } function provision_drupal_find_sites() { if ($dir = opendir("./sites")) { while (FALSE !== ($subdir = readdir($dir))) { // skip internal directory pointers if ($subdir != '.' && $subdir != '..') { $file = "./sites/$subdir/settings.php"; if (file_exists("$file") && ($subdir != 'default') && !is_link("./sites/$subdir")) { $sites[$subdir] = $file; } } } closedir($dir); } else { drush_log(dt("Cannot find sites directory"), 'error'); $sites = FALSE; } return $sites; } function _provision_drupal_get_cvs_versions($files) { foreach ($files as $modulename => $file) { $project = array(); $project['filename'] = $file->filename; $project['name'] = $file->name; $file->info['description'] = str_replace("\n", "", $file->info['description']); if (!isset($project['project'])) { $project['project'] = cvs_deploy_get_project_name($project); } _cvs_deploy_version_alter($file->info['version'], $project); $name = !empty($project['project']) ? $project['project'] : $modulename; $files[$name] = $file; } return $files; } /** * Create and remove symlinks for each of the possible domain aliases of an existing site */ function _provision_drupal_maintain_aliases($url) { if (PROVISION_CONTEXT_SITE) { // First we delete all the old aliases drush_set_option('aliases', drush_get_option('aliases'), 'site'); _provision_drupal_delete_aliases(drush_get_option('aliases', array(), 'site')); if (!drush_get_option('redirection')) { $aliases = drush_get_option('aliases'); if (!is_array($aliases)) { $aliases = explode(",", $aliases); } foreach($aliases as $alias) { if (trim($alias)) { provision_path("symlink", $url, drush_get_option('docroot_path') . "/sites/" . $alias, dt("Created symlink for alias @alias", array("@alias" => $alias)), dt("Could not create symlink for alias @alias", array("@alias" => $alias))); } } } } } /** * Delete a list of aliases */ function _provision_drupal_delete_aliases($aliases) { if (!is_array($aliases)) { $aliases = explode(",", $aliases); } foreach ($aliases as $alias) { if (trim($alias)) { provision_path("unlink", drush_get_option('docroot_path') . "/sites/" . $alias, TRUE, dt("Removed symlink for alias @alias", array("@alias" => $alias)), dt("Could not remove symlink for alias @alias", array("@alias" => $alias))); } } } require_once('cvs_deploy.inc'); function provision_find_packages() { // Load the version specific include files. drush_include_engine('drupal', 'packages', drush_drupal_major_version()); $packages['base'] = _provision_find_packages('base'); // Create a package for the Drupal release $packages['base']['platforms'] = _provision_find_platforms(); // Find install profiles. $profiles = _provision_find_profiles(); drush_set_option('profiles', array_keys((array) $profiles), 'drupal'); // Iterate through the install profiles, finding the profile specific packages foreach ($profiles as $profile => $info) { _provision_cvs_deploy($info); if (!$info->version) { $info->version = drush_drupal_version(); } $packages['base']['profiles'][$profile] = $info; $packages['profiles'][$profile] = _provision_find_packages('profiles', $profile); } // Iterate through the sites, finding site specific packages foreach (drush_get_option('sites', array()) as $site) { $packages['sites'][$site] = _provision_find_packages('sites', $site); } return $packages; } function _provision_find_platforms() { return array( 'drupal' => array( 'short_name' => 'drupal', 'version' => drush_drupal_version(), 'description' => dt("This platform is running @short_name @version", array('@short_name' => 'Drupal', '@version' => VERSION)))); } /** * A small helper function to reduce code duplication */ function _provision_find_packages($scope, $key = '') { $packages = array(); $scope_text = ($key) ? "$scope/$key" : $scope; foreach (array('modules', 'themes') as $type) { $packages[$type] = array(); $func = "_provision_drupal_find_$type"; $result = $func($scope, $key); if (sizeof($result)) { $packages[$type] = $result; drush_log(dt("Found !count !type in !scope", array('!count' => sizeof($result), '!scope' => $scope_text, '!type' => $type))); } } return $packages; } /** * Map the system table to a packages multi-dimensional array component */ function provision_drupal_system_map() { // Load the version specific include files. drush_include_engine('drupal', 'packages'); $profiles = _provision_find_profiles(); foreach ($profiles as $profile => $info) { _provision_cvs_deploy($info); if (!$info->version) { $info->version = drush_drupal_version(); } $profiles[$profile] = $info; } $packages['platforms'] = _provision_find_platforms(); $profile = drush_get_option('profile'); $packages['profiles'][$profile] = $profiles[$profile]; $packages['profiles'][$profile]->status = 1; foreach (_provision_system_query("module") as $module) { $info_file = sprintf("%s/%s.info", dirname($module->filename), $module->name); $module->info = provision_parse_info_file($info_file); _provision_cvs_deploy($module); $module->filename = realpath($module->filename); if ($module->schema_version == -1) { $module->schema_version = 0; } $packages['modules'][$module->name] = $module; } drush_log(dt("Found !count modules", array('!count' => sizeof($packages['modules'])))); foreach (_provision_system_query("theme") as $theme) { $info_file = sprintf("%s/%s.info", dirname($theme->filename), $theme->name); $theme->info = provision_parse_info_file($info_file); _provision_cvs_deploy($theme); $theme->filename = realpath($theme->filename); if ($theme->schema_version == -1) { $theme->schema_version = 0; } $packages['themes'][$theme->name] = $theme; } drush_log(dt("Found !count themes", array('!count' => sizeof($packages['themes'])))); return $packages; } /** * Retrieve a list of paths to search in a certain scope */ function _provision_drupal_search_paths($scope, $key = '', $type = 'modules') { $searchpaths = array(); $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT'); switch ($scope) { case 'base' : $searchpaths[] = sprintf("%s/%s", $drupal_root, $type); $searchpaths[] = sprintf("%s/sites/all/%s", $drupal_root, $type); break; default : if ($key) { $searchpaths[] = sprintf("%s/%s/%s/%s", $drupal_root, $scope, $key, $type); } break; } return $searchpaths; } /** * Find modules in a certain scope. * * This function is general enough that it works for all supported * versions of Drupal. */ function _provision_drupal_find_modules($scope, $key = '') { $paths = _provision_drupal_search_paths($scope, $key, 'modules'); $files = array(); foreach ($paths as $path) { $files = array_merge($files, drush_scan_directory($path, "/\.module$/", array('.', '..', 'CVS', '.svn'), 0, true, 'name')); } foreach ($files as $name => $info) { $install_file = sprintf("%s/%s.install", dirname($info->filename), $name); $schema_version = 0; if (file_exists($install_file)) { $source = file_get_contents(trim($install_file)); $source = str_replace("\r\n", "\n", $source); $source = str_replace("\r", "\n", $source); $function_matches = array(); preg_match_all('!function\s*&?([a-zA-Z0-9_]+)_update_([0-9]+)\(.*?\s*\{!', $source, $function_matches); if (sizeof($function_matches[0])) { $schema_version = max($function_matches[2]); } } $info_file = sprintf("%s/%s.info", dirname($info->filename), $name); $files[$name]->info = provision_parse_info_file($info_file); $files[$name]->schema_version = $schema_version; _provision_cvs_deploy($files[$name]); } return $files; } function provision_parse_info_file($filename) { $info = array(); $defaults = array( 'dependencies' => array(), 'description' => '', 'version' => NULL, 'php' => DRUPAL_MINIMUM_PHP, ); if (file_exists($filename)) { $info = _provision_drupal_parse_info_file($filename); } // Merge in defaults and return return $info + $defaults; } /** * Set up the $_SERVER environment variable so that drupal can correctly parse the settings.php file */ function provision_prepare_environment() { $fields = array('db_type', 'db_host', 'db_user', 'db_passwd', 'db_name'); foreach ($fields as $key) { $_SERVER[$key] = drush_get_option($key, null, 'site'); } }