X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fdrush%2Fdrush%2Fincludes%2Fsitealias.inc;fp=vendor%2Fdrush%2Fdrush%2Fincludes%2Fsitealias.inc;h=5db7a179ca996618ae204e932686c2104ddcc60c;hp=fce233d81120e2581d5e037f41a55aa72aad1fea;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0 diff --git a/vendor/drush/drush/includes/sitealias.inc b/vendor/drush/drush/includes/sitealias.inc index fce233d81..5db7a179c 100644 --- a/vendor/drush/drush/includes/sitealias.inc +++ b/vendor/drush/drush/includes/sitealias.inc @@ -5,176 +5,21 @@ * The site alias API. * * Run commands on remote server(s). - * @see example.aliases.drushrc.php + * @see example.aliases.yml * @see http://drupal.org/node/670460 */ +use Drush\Commands\core\StatusCommands; +use Drush\Drush; use Drush\Log\LogLevel; +use Drush\SiteAlias\AliasRecord; use Webmozart\PathUtil\Path; /** - * Check to see if the user specified an alias - * in an arguement, or via site-set. If so, return - * the name of the alias. - * - * If the alias came from args, then remove it - * from args. - */ -function drush_sitealias_check_arg_and_site_set() { - $args = drush_get_arguments(); - $target_alias = FALSE; - - // Test to see if the first arg is a valid alias identifier. - // If the first arguement is a well-formed identifier, but we - // cannot find a record for it, then we will fail with an error. - if (!empty($args) && drush_sitealias_valid_alias_format($args[0])) { - // Pop the alias off the arguments list first thing. - $target_alias = array_shift($args); - drush_set_arguments($args); - } - else { - // If the user did not specify an alias via an argument, - // check to see if a site env was set. - $target_alias = drush_sitealias_site_get(); - } - - // Record the user's desired target alias name - if ($target_alias) { - drush_set_context('DRUSH_TARGET_SITE_ALIAS', $target_alias); - } - return $target_alias; -} - -/** - * Check to see if the first command-line arg or the - * -l option is a site alias; if it is, copy its record - * values to the 'alias' context. - * - * @return boolean - * TRUE if a site alias was found and processed. - */ -function drush_sitealias_check_arg() { - $args = drush_get_arguments(); - - // Test to see if the first arg is a site specification - if (!empty($args) && _drush_sitealias_set_context_by_name($args[0])) { - drush_set_context('DRUSH_TARGET_SITE_ALIAS', $args[0]); - array_shift($args); - // We only need to expand the site specification - // once, then we are done. - drush_set_arguments($args); - return TRUE; - } - // Return false to indicate that no site alias was specified. - return FALSE; -} - -/* - * Check to see if user has selected a site via site-set command. - */ -function drush_sitealias_check_site_env() { - $site = drush_get_context('DRUSH_TARGET_SITE_ALIAS'); - if (empty($site)) { - $site_env = drush_sitealias_site_get(); - if (!empty($site_env) && (_drush_sitealias_set_context_by_name($site_env))) { - drush_set_context('DRUSH_TARGET_SITE_ALIAS', $site_env); - return TRUE; - } - } - // Return false to indicate that no site alias was specified. - return FALSE; -} - -/** - * Check to see if a '@self' record was created during bootstrap. - * If not, make one now. - */ -function drush_sitealias_create_self_alias() { - $self_record = drush_sitealias_get_record('@self'); - if (!array_key_exists('root', $self_record) && !array_key_exists('remote-host', $self_record)) { - $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT'); - $uri = drush_get_context('DRUSH_SELECTED_URI'); - if (!empty($drupal_root) && !empty($uri)) { - // Create an alias '@self' - _drush_sitealias_cache_alias('@self', array('root' => $drupal_root, 'uri' => $uri)); - } - } -} - -/** - * Given a list of alias records, shorten the name used if possible - */ -function drush_sitealias_simplify_names($site_list) { - $result = array(); - foreach ($site_list as $original_name => $alias_record) { - $adjusted_name = $alias_record['#name']; - $hashpos = strpos($original_name, '#'); - if ($hashpos !== FALSE) { - $adjusted_name = substr($original_name, $hashpos); - if (array_key_exists('remote-host', $alias_record)) { - $adjusted_name = $alias_record['remote-host'] . $adjusted_name; - } - } - $result[$adjusted_name] = $alias_record; - } - return $result; -} - -/** - * Given an array of site specifications, resolve each one in turn and - * return an array of alias records. If you only want a single record, - * it is preferable to simply call drush_sitealias_get_record() directly. - * - * @param $site_specifications - * One of: - * A comma-separated list of site specifications: '@site1,@site2' - * An array of site specifications: array('@site1','@site2') - * An array of alias records: - * array( - * 'site1' => array('root' => ...), - * 'site2' => array('root' => ...) - * ) - * An array of site specifications. - * @see drush_sitealias_get_record() for the format of site specifications. - * @return - * An array of alias records - */ -function drush_sitealias_resolve_sitespecs($site_specifications, $alias_path_context = NULL) { - $result_list = array(); - $not_found = array(); - if (!is_array($site_specifications)) { - $site_specifications = explode(',', $site_specifications); - } - if (!empty($site_specifications)) { - foreach ($site_specifications as $site) { - if (is_array($site)) { - $result_list[] = $site; - } - else { - $alias_record = drush_sitealias_get_record($site, $alias_path_context); - if (!$alias_record) { - $not_found[] = $site; - } - else { - $result_list = array_merge($result_list, drush_sitealias_resolve_sitelist($alias_record)); - } - } - } - } - return array($result_list, $not_found); -} - -/** - * Returns TRUE if $alias is a valid format for an alias name. - * - * Mirrors the allowed formats shown below for drush_sitealias_get_record. + * Option keys used for site selection. */ -function drush_sitealias_valid_alias_format($alias) { - return ( (strpos($alias, ',') !== false) || - ((strpos($alias, '@') === FALSE ? 0 : 1) + (strpos($alias, '/') === FALSE ? 0 : 1) + (strpos($alias, '#') === FALSE ? 0 : 1) >= 2) || - ($alias{0} == '#') || - ($alias{0} == '@') - ); +function drush_sitealias_site_selection_keys() { + return ['remote-host', 'remote-user', 'ssh-options', '#name', 'os']; } /** @@ -209,2119 +54,45 @@ function drush_sitealias_valid_alias_format($alias) { * An alias record, or empty if none found. */ function drush_sitealias_get_record($alias, $alias_context = NULL) { - // Check to see if the alias contains commas. If it does, then - // we will go ahead and make a site list record - $alias_record = array(); - if (strpos($alias, ',') !== false) { - // TODO: If the site list contains any site lists, or site - // search paths, then we should expand those and merge them - // into this list longhand. - $alias_record['site-list'] = explode(',', $alias); - } - else { - $alias_record = _drush_sitealias_get_record($alias, $alias_context); - } - if (!empty($alias_record)) { - if (array_key_exists('#name', $alias_record)) { - if ($alias_record['#name'] == 'self') { - $path = drush_sitealias_local_site_path($alias_record); - if ($path) { - $cached_alias_record = drush_sitealias_lookup_alias_by_path($path); - // Don't overrite keys which have already been negotiated. - unset($cached_alias_record['#name'], $cached_alias_record['root'], $cached_alias_record['uri']); - $alias_record = array_merge($alias_record, $cached_alias_record); - } - } - } - else { - $alias_record['#name'] = drush_sitealias_uri_to_site_dir($alias); - } - } - return $alias_record; -} - -/** - * This is a continuation of drush_sitealias_get_record, above. It is - * not intended to be called directly. - */ -function _drush_sitealias_get_record($alias, $alias_context = NULL) { - $alias_record = array(); - // Before we do anything else, load $alias if it needs to be loaded - _drush_sitealias_load_alias($alias, $alias_context); - - // Check to see if the provided parameter is in fact a defined alias. - $all_site_aliases =& drush_get_context('site-aliases'); - if (array_key_exists($alias, $all_site_aliases)) { - $alias_record = $all_site_aliases[$alias]; - } - // If the parameter is not an alias, then it is some form of - // site specification (or it is nothing at all) - else { - if (isset($alias)) { - // Cases 1.) - 4.): - // We will check for a site specification if the alias has at least - // two characters from the set '@', '/', '#'. - if ((strpos($alias, '@') === FALSE ? 0 : 1) + ((strpos($alias, '/') === FALSE && strpos($alias, '\\') === FALSE) ? 0 : 1) + (strpos($alias, '#') === FALSE ? 0 : 1) >= 2) { - if ((substr($alias,0,7) != 'http://') && !drush_is_absolute_path($alias)) { - // Add on a scheme so that "user:pass@server" will always parse correctly - $parsed = parse_url('http://' . $alias); - } - else if (drush_is_windows() && drush_is_absolute_path($alias)) { - // On windows if alias begins with a filesystem path we must add file:// scheme to make it parse correcly - $parsed = parse_url('file:///' . $alias); - } - else { - $parsed = parse_url($alias); - } - // Copy various parts of the parsed URL into the appropriate records of the alias record - foreach (array('user' => 'remote-user', 'pass' => 'remote-pass', 'host' => 'remote-host', 'fragment' => 'uri', 'path' => 'root') as $url_key => $option_key) { - if (array_key_exists($url_key, $parsed)) { - _drush_sitealias_set_record_element($alias_record, $option_key, $parsed[$url_key]); - } - } - // If the site specification has a query, also set the query items - // in the alias record. This allows passing db_url as part of the - // site specification, for example. - if (array_key_exists('query', $parsed)) { - foreach (explode('&', $parsed['query']) as $query_arg) { - $query_components = explode('=', $query_arg); - _drush_sitealias_set_record_element($alias_record, urldecode($query_components[0]), urldecode($query_components[1])); - } - } - - // Case 3.): If the URL contains a 'host' portion but no fragment, then set the uri to the host - // Note: We presume that 'server' is the best default for case 3; without this code, the default would - // be whatever is set in $options['l'] on the target machine's drushrc.php settings file. - if (array_key_exists('host', $parsed) && !array_key_exists('fragment', $parsed)) { - $alias_record['uri'] = $parsed['host']; - } - - // Special checking: relative aliases embedded in a path - $relative_alias_pos = strpos($alias_record['root'], '/@'); - if ($relative_alias_pos !== FALSE) { - // Special checking: /path/@sites - $base = substr($alias_record['root'], 0, $relative_alias_pos); - $relative_alias = substr($alias_record['root'], $relative_alias_pos + 1); - if (drush_valid_root($base) || ($relative_alias == '@sites')) { - drush_sitealias_create_sites_alias($base); - $alias_record = drush_sitealias_get_record($relative_alias); - } - else { - $alias_record = array(); - } - } - } - else { - // Case 5.) and 6.): - // If the alias is the name of a folder in the 'sites' directory, - // then use it as a local site specification. - $alias_record = _drush_sitealias_find_record_for_local_site($alias); - } - } - } - - if (!empty($alias_record)) { - if (!isset($alias_record['remote']) && !isset($alias_record['#loaded-config'])) { - if (array_key_exists('root', $alias_record)) { - drush_sitealias_add_to_alias_path($alias_record['root'] . '/drush'); - drush_sitealias_add_to_alias_path($alias_record['root'] . '/sites/all/drush'); - } - // TODO: We should probably remove this feature, and put it back - // in, but in different places (e.g. site selection, sql-sync + rsync - // parameters, etc.) - $alias_site_dir = drush_sitealias_local_site_path($alias_record); - - if (isset($alias_site_dir)) { - // Add the sites folder of this site to the alias search path list - drush_sitealias_add_to_alias_path($alias_site_dir); - } - if (isset($alias_record['config']) && file_exists($alias_record['config'])) { - drush_load_config_file('site', $alias_record['config']); - $alias_record['#loaded-config'] = TRUE; - } - unset($alias_record['config']); - } - - // Add the static defaults - _drush_sitealias_add_static_defaults($alias_record); - - // Cache the result with all of its calculated values - $all_site_aliases[$alias] = $alias_record; - } - - return $alias_record; -} - -/** - * Add a path to the array of paths where alias files are searched for. - * - * @param $add_path - * A path to add to the search path (or NULL to not add any). - * Once added, the new path will remain available until drush - * exits. - * @return - * An array of paths containing all values added so far - */ -function drush_sitealias_add_to_alias_path($add_path) { - static $site_paths = array(); - - if ($add_path != NULL) { - if (!is_array($add_path)) { - $add_path = explode(PATH_SEPARATOR, $add_path); - } - // Normalize path to make sure we don't add the same path twice on - // windows due to different spelling. e.g. c:\tmp and c:/tmp - foreach($add_path as &$path) { - $path = drush_normalize_path($path); - } - $site_paths = array_unique(array_merge($site_paths, $add_path)); - } - return $site_paths; -} - -/** - * Return the array of paths where alias files are searched for. - * - * @param $alias_path_context - * If the alias being looked up is part of a relative alias, - * the alias path context specifies the context of the primary - * alias the new alias is rooted from. Alias files stored in - * the sites folder of this context, or inside the context itself - * takes priority over any other search path that might define - * a similarly-named alias. In this way, multiple sites can define - * a '@peer' alias. - * @return - * An array of paths - */ -function drush_sitealias_alias_path($alias_path_context = NULL) { - $context_path = array(); - if (isset($alias_path_context)) { - $context_path = array(drush_sitealias_local_site_path($alias_path_context)); - } - // We get the current list of site paths by adding NULL - // (nothing) to the path list, which is a no-op - $site_paths = drush_sitealias_add_to_alias_path(NULL); - - // If the user defined the root of a drupal site, then also - // look for alias files in /drush and /sites/all/drush. - $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT'); - if (!empty($drupal_root)) { - $site_paths[] = drush_sitealias_alias_base_directory($drupal_root . '/../drush'); - $site_paths[] = drush_sitealias_alias_base_directory($drupal_root . '/drush'); - $site_paths[] = drush_sitealias_alias_base_directory($drupal_root . '/sites/all/drush'); - $uri = drush_get_context('DRUSH_SELECTED_URI'); - if (empty($uri)) { - $uri = 'default'; - } - $site_dir = drush_sitealias_uri_to_site_dir($uri, $drupal_root); - if ($site_dir) { - $site_paths[] = drush_sitealias_alias_base_directory("$drupal_root/sites/$site_dir"); - } - } - $alias_path = (array) drush_get_context('ALIAS_PATH', array()); - return array_unique(array_merge($context_path, $alias_path, $site_paths)); -} - -/** - * If there is a directory 'site-aliases' in the specified search location, - * then search ONLY in that directory for aliases. Otherwise, search - * anywhere inside the specified directory for aliases. - */ -function drush_sitealias_alias_base_directory($dir) { - $potential_location = $dir . '/site-aliases'; - if (is_dir($potential_location)) { - return $potential_location; + // If legacy code is still looking for an alias record this way, redirect the + // request to the alias manager. + $alias_record = Drush::aliasManager()->get($alias); + if (empty($alias_record)) { + return []; } - return $dir; + $config_record = $alias_record->exportConfig(); + $exported_config = $config_record->export(); + return isset($exported_config['options']) ? $exported_config['options'] : []; } /** - * Return the full path to the site directory of the - * given alias record. - * - * @param $alias_record - * The alias record - * @return - * The path to the site directory of the associated - * alias record, or NULL if the record is not a local site. - */ -function drush_sitealias_local_site_path($alias_record) { - $result = NULL; - - if (isset($alias_record['root']) && !isset($alias_record['remote-host'])) { - if (isset($alias_record['uri'])) { - $uri = $alias_record['uri']; - $uri = preg_replace('#^[^:]*://#', '', $uri); - while (!$result && !empty($uri)) { - if (file_exists($alias_record['root'] . '/sites/sites.php')) { - $sites = array(); - include($alias_record['root'] . '/sites/sites.php'); - if (array_key_exists($uri, $sites)) { - $result = $alias_record['root'] . '/sites/' . $sites[$uri]; - } - } - if (!$result) { - $result = ($alias_record['root'] . '/sites/' . drush_sitealias_uri_to_site_dir($uri, drush_sitealias_get_root($alias_record))); - } - $result = realpath($result); - $uri = preg_replace('#^[^.]*\.*#', '', $uri); - } - } - if (!$result) { - $result = realpath($alias_record['root'] . '/sites/default'); - } - } - - return $result; -} - -/** - * Check and see if an alias definition for $alias is available. - * If it is, load it into the list of aliases cached in the - * 'site-aliases' context. - * - * @param $alias - * The name of the alias to load in ordinary form ('@name') - * @param $alias_path_context - * When looking up a relative alias, the alias path context is - * the primary alias that we will start our search from. - */ -function _drush_sitealias_load_alias($alias, $alias_path_context = NULL) { - $all_site_aliases = drush_get_context('site-aliases'); - $result = array(); - - // Only aliases--those named entities that begin with '@'--can be loaded this way. - // We also skip any alias that has already been loaded. - if ((substr($alias,0,1) == '@') && !array_key_exists($alias,$all_site_aliases)) { - $aliasname = substr($alias,1); - $result = _drush_sitealias_find_and_load_alias($aliasname, $alias_path_context); - if (!empty($result)) { - $alias_options = array('site-aliases' => array($aliasname => $result)); - _drush_sitealias_add_inherited_values($alias_options['site-aliases']); - drush_set_config_special_contexts($alias_options); - if (array_key_exists('#file', $result)) { - drush_log(dt('Loaded alias !alias from file !file', array('!alias' => $alias, '!file' => $result['#file']))); - } - } - } - - return $result; -} - -/** - * Load every alias file that can be found anywhere in the - * alias search path. - */ -function drush_sitealias_load_all($resolve_parent = TRUE) { - $result = _drush_sitealias_find_and_load_all_aliases(); - if (!empty($result) && ($resolve_parent == TRUE)) { - // If any aliases were returned, then check for - // inheritance and then store the aliases into the - // alias cache - _drush_sitealias_add_inherited_values($result); - $alias_options = array('site-aliases' => $result); - drush_set_config_special_contexts($alias_options); - } -} - -/** - * Worker function called by _drush_sitealias_load_alias and - * drush_sitealias_load_all. Traverses the alias search path - * and finds the specified alias record. + * Determines whether a given site alias is for a remote site. * - * @return - * An array of $kay => $value pair of alias names and alias records - * loaded. - */ -function _drush_sitealias_find_and_load_all_aliases() { - $result = array(); - - $drush_alias_files = _drush_sitealias_find_alias_files(); - drush_set_context('drush-alias-files', $drush_alias_files); - - // For every file that matches, check inside it for - // an alias with a matching name. - foreach ($drush_alias_files as $filename) { - if (file_exists($filename)) { - $aliases = $options = array(); - // silently ignore files we can't include - if ((@include $filename) === FALSE) { - drush_log(dt('Cannot open alias file "!alias", ignoring.', array('!alias' => realpath($filename))), LogLevel::BOOTSTRAP); - continue; - } - unset($options['site-aliases']); // maybe unnecessary - - // If $aliases are not set, but $options are, then define one alias named - // after the first word of the file, before '.alias.drushrc.php. - if (empty($aliases) && !empty($options)) { - $this_alias_name = substr(basename($filename),0,strpos(basename($filename),'.')); - $aliases[$this_alias_name] = $options; - $options = array(); - } - // If this is a group alias file, then make an - // implicit alias from the group name that contains - // a site-list of all of the aliases in the file - $group_name = ''; - if (substr($filename, -20) == ".aliases.drushrc.php") { - $group_name = basename($filename,".aliases.drushrc.php"); - if (!empty($aliases) && !array_key_exists($group_name, $aliases)) { - $alias_names = array(); - foreach (array_keys($aliases) as $one_alias) { - $alias_names[] = "@$group_name.$one_alias"; - $aliases["$group_name.$one_alias"] = $aliases[$one_alias]; - unset($aliases[$one_alias]); - } - $aliases[$group_name] = array('site-list' => implode(',', $alias_names)); - } - } - if (!empty($aliases)) { - if (!empty($options)) { - foreach ($aliases as $name => $value) { - $aliases[$name] = array_merge($options, $value); - } - $options = array(); - } - - foreach ($aliases as $name => $value) { - _drush_sitealias_initialize_alias_record($aliases[$name]); - $aliases[$name]['#name'] = $name; - $aliases[$name]['#file'] = $filename; - } - - $result = _sitealias_array_merge($result, $aliases); - // If we found at least one alias from this file - // then record it in the drush-alias-files context. - $drush_alias_files = drush_get_context('drush-alias-files'); - if (!in_array($filename, $drush_alias_files)) { - $drush_alias_files[] = $filename; - } - drush_set_context('drush-alias-files', $drush_alias_files); - } - } - } - - return $result; -} - -/** - * Function to find all alias files that might contain aliases - * that match the requested alias name. - */ -function _drush_sitealias_find_alias_files($aliasname = NULL, $alias_path_context = NULL) { - $alias_files_to_consider = array(); - - // The alias path is a list of folders to search for alias settings files - $alias_path = drush_sitealias_alias_path($alias_path_context); - - // $alias_files contains a list of filename patterns - // to search for. We will find any matching file in - // any folder in the alias path. The directory scan - // is not deep, though; only files immediately in the - // search path are considered. - $alias_files = array('/.*aliases\.drush(' . DRUSH_MAJOR_VERSION . '|)rc\.php$/'); - if ($aliasname == NULL) { - $alias_files[] = '/.*\.alias\.drush(' . DRUSH_MAJOR_VERSION . '|)rc\.php$/'; - } - else { - $alias_files[] = '/' . preg_quote($aliasname, '/') . '\.alias\.drush(' . DRUSH_MAJOR_VERSION . '|)rc\.php$/'; - } - - // Do not scan into the files directory. - $blacklist = array_merge(array('files'), drush_filename_blacklist()); - - // Search each path in turn. - foreach ($alias_path as $path) { - // Find all of the matching files in this location - foreach ($alias_files as $file_pattern_to_search_for) { - drush_log(dt('Scanning into @path for @pattern', array('@path' => $path, '@pattern' => $file_pattern_to_search_for)), LogLevel::DEBUG_NOTIFY); - $alias_files_to_consider = array_merge($alias_files_to_consider, array_keys(drush_scan_directory($path, $file_pattern_to_search_for, $blacklist, 0, TRUE))); - } - } - - return $alias_files_to_consider; -} - -/** - * Traverses the alias search path and finds the specified alias record. + * @param string $alias + * An alias name or site specification. * - * @param $aliasname - * The name of the alias without the leading '@' (i.e. '#name') - * or NULL to load every alias found in every alias file. - * @param $alias_path_context - * When looking up a relative alias, the alias path context is - * the primary alias that we will start our search from. - * @return - * An empty array if nothing was loaded. If $aliasname is - * not null, then the array returned is the alias record for - * $aliasname. If $aliasname is NULL, then the array returned - * is a $kay => $value pair of alias names and alias records - * loaded. + * @return bool + * Returns TRUE if the alias refers to a remote site, FALSE if it does not, or NULL is unsure. */ -function _drush_sitealias_find_and_load_alias($aliasname, $alias_path_context = NULL) { - // Special checking for '@sites' alias - if ($aliasname == 'sites') { - $drupal_root = NULL; - if ($alias_path_context != null) { - if (array_key_exists('root', $alias_path_context) && !array_key_exists('remote-host', $alias_path_context)) { - $drupal_root = $alias_path_context['root']; - } - } - else { - $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT'); - } - if (isset($drupal_root) && !is_array($drupal_root)) { - drush_sitealias_create_sites_alias($drupal_root); - } - } - - $alias_files_to_consider = _drush_sitealias_find_alias_files($aliasname, $alias_path_context); - - return _drush_sitealias_find_and_load_alias_from_file($aliasname, $alias_files_to_consider); -} - -function _drush_sitealias_find_and_load_alias_from_file($aliasname, $alias_files_to_consider) { - $result = array(); - $result_names = array(); - - // For every file that matches, check inside it for - // an alias with a matching name. - $recorded_files = array(); - foreach ($alias_files_to_consider as $filename) { - if (file_exists($filename)) { - $aliases = $options = array(); - // silently ignore files we can't include - if ((@include $filename) === FALSE) { - drush_log(dt('Cannot open alias file "!alias", ignoring.', array('!alias' => realpath($filename))), LogLevel::BOOTSTRAP); - continue; - } - unset($options['site-aliases']); // maybe unnecessary - - // If $aliases are not set, but $options are, then define one alias named - // after the first word of the file, before '.alias.drushrc.php. - if (empty($aliases) && !empty($options)) { - $this_alias_name = substr(basename($filename),0,strpos(basename($filename),'.')); - $aliases[$this_alias_name] = $options; - $options = array(); - } - // If this is a group alias file, then make an - // implicit alias from the group name that contains - // a site-list of all of the aliases in the file - $group_prefix = ''; - if (substr($filename, -20) == ".aliases.drushrc.php") { - $group_name = basename($filename,".aliases.drushrc.php"); - $group_prefix = $group_name . '.'; - if (!empty($aliases) && !array_key_exists($group_name, $aliases)) { - $alias_names = array(); - foreach (array_keys($aliases) as $one_alias) { - $alias_names[] = "@$group_name.$one_alias"; - $aliases[$one_alias]['#name'] = "$group_name.$one_alias"; - $aliases[$one_alias]['#group'] = $group_name; - $aliases["$group_name.$one_alias"] = $aliases[$one_alias]; - $aliases[$one_alias]["#hidden"] = TRUE; - } - $aliases[$group_name] = array('site-list' => implode(',', $alias_names), '#group' => $group_name, '#name' => $group_name); - } - } - // Store only the named alias into the alias cache - if ((isset($aliases)) && !empty($aliasname) && array_key_exists($aliasname, $aliases)) { - drush_set_config_special_contexts($options); // maybe unnecessary - $one_result = array_merge($options, $aliases[$aliasname]); - $one_result['#file'] = $filename; - if (!array_key_exists('#name', $one_result)) { - $one_result['#name'] = $aliasname; - } - _drush_sitealias_initialize_alias_record($one_result); - // If the alias name is exactly the same as a previous match, then - // merge the two records together - if (!empty($result) && ($result['#name'] == $one_result['#name'])) { - $result = _sitealias_array_merge($result, $one_result); - } - // Add the name of the found record to the list of results - else { - $result_names[] = "@" . $one_result['#name']; - $result = $one_result; - } - } - } +function drush_sitealias_is_remote_site($alias) { + if (is_array($alias) && !empty($alias['remote-host'])) { + return TRUE; } - // If there are multiple matches, then return a list of results. - if (count($result_names) > 1) { - $result = array('site-list' => $result_names); + if (!is_string($alias) || !strlen($alias)) { + return NULL; } - return $result; -} - -/** - * Merges two site aliases. - * - * array_merge_recursive is too much; we only want to run - * array_merge on the common top-level keys of the array. - * - * @param array $site_alias_a - * A site alias array. - * @param array $site_alias_b - * A site alias array. - * @return - * A site alias array where the keys from $site_alias_a are overwritten by the - * keys from $site_alias_b. - */ -function _sitealias_array_merge($site_alias_a, $site_alias_b) { - $result = $site_alias_a; - - foreach($site_alias_b as $key => $value) { - if (is_array($value) && array_key_exists($key, $result)) { - $result[$key] = array_merge($result[$key], $value); + $site_record = drush_sitealias_get_record($alias); + if ($site_record) { + if (!empty($site_record['remote-host'])) { + return TRUE; } else { - $result[$key] = $value; - } - } - - return $result; -} - -/** - * Check to see if there is a 'parent' item in the alias; if there is, - * then load the parent alias record and overlay the entries in the - * current alias record on top of the items from the parent record. - * - * @param $aliases - * An array of alias records that are modified in-place. - */ -function _drush_sitealias_add_inherited_values(&$aliases) { - foreach ($aliases as $alias_name => $alias_value) { - // Prevent circular references from causing an infinite loop - _drush_sitealias_cache_alias("@$alias_name", array()); - _drush_sitealias_add_inherited_values_to_record($alias_value); - $aliases[$alias_name] = $alias_value; - } -} - -function _drush_sitealias_add_inherited_values_to_record(&$alias_value) { - drush_command_invoke_all_ref('drush_sitealias_alter', $alias_value); - if (isset($alias_value['parent'])) { - drush_log(dt("Using deprecated 'parent' element '!parent' in '!name'.", array('!parent' => $alias_value['parent'], '!name' => $alias_value['#name'])), LogLevel::DEBUG); - // Fetch and merge in each parent - foreach (explode(',', $alias_value['parent']) as $parent) { - $parent_record = drush_sitealias_get_record($parent); - unset($parent_record['#name']); - unset($parent_record['#file']); - unset($parent_record['#hidden']); - $array_based_keys = array_merge(drush_get_special_keys(), array('path-aliases')); - foreach ($array_based_keys as $array_based_key) { - if (isset($alias_value[$array_based_key]) && isset($parent_record[$array_based_key])) { - $alias_value[$array_based_key] = array_merge($parent_record[$array_based_key], $alias_value[$array_based_key]); - } - } - $alias_value = array_merge($parent_record, $alias_value); - } - } - unset($alias_value['parent']); -} - -/** - * Add an empty record for the specified alias name - * - * @param $alias_name - * The name of the alias, including the leading "@" - */ -function _drush_sitealias_cache_alias($alias_name, $alias_record) { - $cache =& drush_get_context('site-aliases'); - // If the alias already exists in the cache, then merge - // the new alias with the existing alias - if (array_key_exists($alias_name, $cache)) { - $alias_record = array_merge($cache[$alias_name], $alias_record); - } - if (!isset($alias_record['#name'])) { - $alias_record['#name'] = trim($alias_name, '@'); - } - $cache[$alias_name] = $alias_record; - - // If the alias record points at a local site, make sure - // that /drush, /sites/all/drush and the site folder for that site - // are added to the alias path, so that other alias files - // stored in those locations become searchable. - if (!array_key_exists('remote-host', $alias_record) && !empty($alias_record['root'])) { - drush_sitealias_add_to_alias_path($alias_record['root'] . '/drush'); - drush_sitealias_add_to_alias_path($alias_record['root'] . '/sites/all/drush'); - $site_dir = drush_sitealias_local_site_path($alias_record); - if (isset($site_dir)) { - drush_sitealias_add_to_alias_path($site_dir); - } - } -} - -/** - * If the alias record does not contain a 'databases' or 'db-url' - * entry, then use backend invoke to look up the settings value - * from the remote or local site. The 'db_url' form is preferred; - * nothing is done if 'db_url' is not available (e.g. on a D7 site) - * - * @param $alias_record - * The full alias record to populate with database settings - */ -function drush_sitealias_add_db_url(&$alias_record) { - if (!isset($alias_record['db-url']) && !isset($alias_record['databases']) && !isset($alias_record['site-list'])) { - drush_sitealias_add_db_settings($alias_record); - } - if (!isset($alias_record['db-url']) && isset($alias_record['databases'])) { - $alias_record['db-url'] = drush_sitealias_convert_databases_to_db_url($alias_record['databases']); - } -} - -/** - * Drush still accepts --db-url format database specifications as - * cli parameters; it is therefore useful to be able to convert - * from a database record back to a db-url sometimes. - */ -function drush_sitealias_convert_db_spec_to_db_url($db_spec) { - $result = urlencode($db_spec["driver"]) . "://"; - if (isset($db_spec["username"])) { - $result .= urlencode($db_spec["username"]); - if (isset($db_spec["password"])) { - $result .= ":" . urlencode($db_spec["password"]); - } - $result .= "@"; - } - // Host is required, unless this is an sqlite db. - if (isset($db_spec["host"])) { - $result .= urlencode($db_spec["host"]); - if (isset($db_spec["port"])) { - $result .= ":" . urlencode($db_spec["port"]); + return FALSE; } - $result .= '/' . urlencode($db_spec["database"]); } else { - // URL-encode the database, but convert slashes - // back to their original form for readability. - // This portion is the "path" of the URL, so it may - // contain slashes. This is important for sqlite. - $result .= str_replace("%2F", "/", urlencode(ltrim($db_spec["database"], '/'))); - } - return $result; -} - -/** - * Create a db-url from the databases record. - */ -function drush_sitealias_convert_databases_to_db_url($databases) { - if ((count($databases) == 1) && isset($databases['default'])) { - $result = drush_sitealias_convert_db_spec_to_db_url($databases['default']['default']); - } - else { - foreach ($databases as $key => $db_info) { - $result[$key] = drush_sitealias_convert_db_spec_to_db_url($db_info['default']); - } - } - return $result; -} - -/** - * Return the databases record from the alias record - * - * @param $alias_record - * A record returned from drush_sitealias_get_record - * @returns - * A databases record (always in D7 format) or NULL - * if the databases record could not be found. - */ -function sitealias_get_databases_from_record(&$alias_record) { - $altered_record = drush_sitealias_add_db_settings($alias_record); - - return array_key_exists('databases', $alias_record) ? $alias_record['databases'] : NULL; -} - -/** - * Return the $db_spec record for the database associated with - * the provided alias record. @see drush_sitealias_add_db_settings(), - * which will be used to first add the database information to the - * alias records, invoking sql-conf to look them up if necessary. - * - * The options 'database' and 'target' are used to specify which - * specific database should be fetched from the database record; - * they may appear in the alias definition, or may be taken from the - * command line options. The values 'default' and 'default' are - * used if these options are not specified in either location. - * - * Note that in the context of sql-sync, the site alias record will - * be taken from one of the source or target aliases - * (e.g. `drush sql-sync @source @target`), which will be overlayed with - * any options that begin with 'source-' or 'target-', respectively. - * Therefore, the commandline options 'source-database' and 'source-target' - * (or 'target-database' and 'source-target') may also affect the operation - * of this function. - */ -function drush_sitealias_get_db_spec(&$alias_record, $default_to_self = FALSE, $prefix = '') { - $db_spec = NULL; - $databases = sitealias_get_databases_from_record($alias_record); - if (isset($databases) && !empty($databases)) { - $database = drush_sitealias_get_option($alias_record, 'database', 'default', $prefix); - $target = drush_sitealias_get_option($alias_record, 'target', 'default', $prefix); - if (array_key_exists($database, $databases) && array_key_exists($target, $databases[$database])) { - $db_spec = $databases[$database][$target]; - } - } - elseif ($default_to_self) { - $db_spec = _drush_sql_get_db_spec(); - } - - if (isset($db_spec)) { - $remote_host = drush_sitealias_get_option($alias_record, 'remote-host', NULL, $prefix); - if (!drush_is_local_host($remote_host)) { - $db_spec['remote-host'] = $remote_host; - $db_spec['port'] = drush_sitealias_get_option($alias_record, 'remote-port', (isset($db_spec['port']) ? $db_spec['port'] : NULL), $prefix); - } - } - - return $db_spec; -} - -/** - * If the alias record does not contain a 'databases' or 'db-url' - * entry, then use backend invoke to look up the settings value - * from the remote or local site. The 'databases' form is - * preferred; 'db_url' will be converted to 'databases' if necessary. - * - * @param $alias_record - * The full alias record to populate with database settings - */ -function drush_sitealias_add_db_settings(&$alias_record) { - $altered_record = FALSE; - if (isset($alias_record['root'])) { - // If the alias record does not have a defined 'databases' entry, - // then we'll need to look one up - if (!isset($alias_record['db-url']) && !isset($alias_record['databases']) && !isset($alias_record['site-list'])) { - $values = drush_invoke_process($alias_record, "sql-conf", array(), array('all' => TRUE), array('integrate' => FALSE, 'override-simulated' => TRUE)); - if (is_array($values) && ($values['error_status'] == 0)) { - $altered_record = TRUE; - // If there are any special settings in the '@self' record returned by drush_invoke_process, - // then add those into our altered record as well - if (array_key_exists('self', $values)) { - $alias_record = array_merge($values['self'], $alias_record); - } - drush_sitealias_cache_db_settings($alias_record, $values['object']); - } - } + drush_set_error('Unrecognized site alias.'); } - return $altered_record; } -function drush_sitealias_cache_db_settings(&$alias_record, $databases) { - if (!empty($databases)) { - $alias_record['databases'] = $databases; - } - - // If the name is set, then re-cache the record after we fetch the databases - if (array_key_exists('#name', $alias_record)) { - $all_site_aliases =& drush_get_context('site-aliases'); - $all_site_aliases['@' . $alias_record['#name']] = $alias_record; - // Check and see if this record is a copy of 'self' - if (($alias_record['#name'] != 'self') && array_key_exists('@self', $all_site_aliases) && array_key_exists('#name', $all_site_aliases['@self']) && ($all_site_aliases['@self']['#name'] == $alias_record['#name'])) { - $all_site_aliases['@self'] = $alias_record; - } - } -} - -/** - * Check to see if we have already bootstrapped to a site. - */ -function drush_sitealias_is_bootstrapped_site($alias_record) { - if (!isset($alias_record['remote-host']) && array_key_exists('root', $alias_record)) { - $self_record = drush_sitealias_get_record("@self"); - if (empty($self_record) || !array_key_exists('root', $self_record)) { - // TODO: If we have not bootstrapped to a site yet, we could - // perhaps bootstrap to $alias_record here. - return FALSE; - } - elseif(($alias_record['root'] == $self_record['root']) && ($alias_record['uri'] == $self_record['uri'])) { - return TRUE; - } - } - return FALSE; -} - -/** - * Determines whether a given site alias is for a remote site. - * - * @param string $alias - * An alias name or site specification. - * - * @return bool - * Returns TRUE if the alias refers to a remote site, FALSE if it does not, or NULL is unsure. - */ -function drush_sitealias_is_remote_site($alias) { - if (is_array($alias) && !empty($alias['remote-host'])) { - return TRUE; - } - if (!is_string($alias) || !strlen($alias)) { - return NULL; - } - - $site_record = drush_sitealias_get_record($alias); - if ($site_record) { - if (!empty($site_record['remote-host'])) { - return TRUE; - } - else { - return FALSE; - } - } - else { - drush_set_error('Unrecognized site alias.'); - } -} - -/** - * Get the name of the current bootstrapped site - */ -function drush_sitealias_bootstrapped_site_name() { - $site_name = NULL; - $self_record = drush_sitealias_get_record('@self'); - if (array_key_exists('#name', $self_record)) { - $site_name = $self_record['#name']; - } - if (!isset($site_name) || ($site_name == '@self')) { - $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT'); - if (isset($drupal_root)) { - $drupal_uri = drush_get_context('DRUSH_SELECTED_URI', 'default'); - $drupal_uri = str_replace('http://', '', $drupal_uri); - // TODO: Maybe use _drush_sitealias_find_local_alias_name? - $site_name = $drupal_root . '#' . $drupal_uri; - } - } - return $site_name; -} - -/** - * If there are any path aliases (items beginning with "%") in the test - * string, then resolve them as path aliases and add them to the provided - * alias record. - * - * @param $alias_record - * The full alias record to use in path alias expansion - * @param $test_string - * A slash-separated list of path aliases to resolve - * e.g. "%files/%special". - */ -function drush_sitealias_resolve_path_references(&$alias_record, $test_string = '') { - $path_aliases = array_key_exists('path-aliases', $alias_record) ? $alias_record['path-aliases'] : array(); - // Convert the test string into an array of items, and - // from this make a comma-separated list of projects - // that we can pass to 'drush status'. - $test_array = explode('/', $test_string); - $project_array = array(); - foreach($test_array as $one_item) { - if (!empty($one_item) && ($one_item[0] == '%') && (!array_key_exists($one_item,$path_aliases))) { - $project_array[] = substr($one_item,1); - } - } - $project_list = implode(',', $project_array); - - if (!empty($project_array)) { - // Optimization: if we're already bootstrapped to the - // site specified by $alias_record, then we can just - // call _core_site_status_table() rather than use backend invoke. - if (drush_sitealias_is_bootstrapped_site($alias_record) && drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) { - $status_values = _core_site_status_table($project_list); - } - else { - $values = drush_invoke_process($alias_record, "core-status", array(), empty($project_list) ? array() : array('project' => $project_list), array('integrate' => FALSE, 'override-simulated' => TRUE)); - $status_values = $values['object']; - } - if (isset($status_values['%paths'])) { - foreach ($status_values['%paths'] as $key => $path) { - $alias_record['path-aliases'][$key] = $path; - } - } - // If 'root' is not set in the alias, then fill it in from the status values. - if (!isset($alias_record['root']) && isset($status_values['root'])) { - $alias_record['root'] = $status_values['root']; - } - } -} - -/** - * Given an alias record that is a site list (contains a 'site-list' entry), - * resolve all of the members of the site list and return them - * is an array of alias records. - * - * @param $alias_record - * The site list alias record array - * @return - * An array of individual site alias records - */ -function drush_sitealias_resolve_sitelist($alias_record) { - $result_list = array(); - if (isset($alias_record)) { - if (array_key_exists('site-list', $alias_record)) { - foreach ($alias_record['site-list'] as $sitespec) { - $one_result = drush_sitealias_get_record($sitespec); - $result_list = array_merge($result_list, drush_sitealias_resolve_sitelist($one_result)); - } - } - elseif (array_key_exists('#name', $alias_record)) { - $result_list[$alias_record['#name']] = $alias_record; - } - } - - return $result_list; -} - -function _drush_sitelist_find_in_list($one_source, &$target) { - $result = FALSE; - - foreach ($target as $key => $one_target) { - if(_drush_sitelist_check_site_records($one_source, $one_target)) { - $result = $one_target; - unset($target[$key]); - } - } - - return $result; -} - -function _drush_sitelist_check_site_records($source, $target) { - if ((array_key_exists('uri', $source)) && (array_key_exists('uri', $target)) && ($source['uri'] == $target['uri'])) { - return TRUE; - } - return FALSE; -} - -/** - * Initialize an alias record; called as soon as the alias - * record is loaded from its alias file, before it is stored - * in the cache. - * - * @param alias_record - * The alias record to be initialized; parameter is modified in place. - */ -function _drush_sitealias_initialize_alias_record(&$alias_record) { - // If there is a 'from-list' entry, then build a derived - // list based on the site list with the given name. - if (array_key_exists('from-list', $alias_record)) { - // danger of infinite loops... move to transient defaults? - $from_record = drush_sitealias_get_record($alias_record['from-list']); - $from_list = drush_sitealias_resolve_sitelist($from_record); - $derived_list = array(); - foreach ($from_list as $one_record) { - $derived_record = _drush_sitealias_derive_record($one_record, $alias_record); - $derived_list[] = drush_sitealias_alias_record_to_spec($derived_record); - } - - $alias_record = array(); - if (!empty($derived_list)) { - $alias_record['site-list'] = $derived_list; - } - } - // If there is a 'site-search-path' entry, then build - // a 'site-list' entry from all of the sites that can be - // found in the search path. - if (array_key_exists('site-search-path', $alias_record)) { - // TODO: Is there any point in merging the sites from - // the search path with any sites already listed in the - // 'site-list' entry? For now we'll just overwrite. - $search_path = $alias_record['site-search-path']; - if (!is_array($search_path)) { - $search_path = explode(',', $search_path); - } - $found_sites = _drush_sitealias_find_local_sites($search_path); - $alias_record['site-list'] = $found_sites; - // The 'unordered-list' flag indicates that the order of the items in the site list is not stable. - $alias_record['unordered-list'] = '1'; - // DEBUG: var_export($alias_record, FALSE); - } - if (array_key_exists('site-list', $alias_record)) { - if (!is_array($alias_record['site-list'])) { - $alias_record['site-list'] = explode(',', $alias_record['site-list']); - } - } - else { - if (isset($alias_record['root']) && !isset($alias_recort['uri'])) { - $alias_recort['uri'] = 'default'; - } - } -} - -/** - * Add "static" default values to the given alias record. The - * difference between a static default and a transient default is - * that static defaults -always- exist in the alias record, and - * they are cached, whereas transient defaults are only added - * if the given drush command explicitly adds them. - * - * @param alias_record - * An alias record with most values already filled in - */ -function _drush_sitealias_add_static_defaults(&$alias_record) { - // If there is a 'db-url' entry but not 'databases' entry, then we will - // build 'databases' from 'db-url' so that drush commands that use aliases - // can always count on using a uniform 'databases' array. - if (isset($alias_record['db-url']) && !isset($alias_record['databases'])) { - $alias_record['databases'] = drush_sitealias_convert_db_from_db_url($alias_record['db-url']); - } - - // Canonicalize paths. - if (!empty($alias_record['root'])) { - $alias_record['root'] = Path::canonicalize($alias_record['root']); - } - - // Adjustments for aliases to drupal instances (as opposed to aliases that are site lists) - if (array_key_exists('uri', $alias_record)) { - // Make sure that there is always a 'path-aliases' array - if (!array_key_exists('path-aliases', $alias_record)) { - $alias_record['path-aliases'] = array(); - } - // If there is a 'root' entry, then copy it to the '%root' path alias - if (isset($alias_record['root'])) { - $alias_record['path-aliases']['%root'] = $alias_record['root']; - } - } -} - -function _drush_sitealias_derive_record($from_record, $modifying_record) { - $result = $from_record; - - // If there is a 'remote-user' in the modifying record, copy it. - if (array_key_exists('remote-user', $modifying_record)) { - $result['remote-user'] = $from_record['remote_user']; - } - // If there is a 'remote-host', then: - // If it is empty, clear the remote host in the result record - // If it ends in '.', then prepend it to the remote host in the result record - // Otherwise, copy it to the result record - if (array_key_exists('remote-host', $modifying_record)) { - $remote_host_modifier = $modifying_record['remote-host']; - if(empty($remote_host_modifier)) { - unset($result['remote-host']); - unset($result['remote-user']); - } - elseif ($remote_host_modifier[strlen($remote_host_modifier)-1] == '.') { - $result['remote-host'] = $remote_host_modifier . $result['remote-host']; - } - else { - $result['remote-host'] = $remote_host_modifier; - } - } - // If there is a 'root', then: - // If it begins with '/', copy it to the result record - // Otherwise, append it to the result record - if (array_key_exists('root', $modifying_record)) { - $root_modifier = $modifying_record['root']; - if($root_modifier[0] == '/') { - $result['root'] = $root_modifier; - } - else { - $result['root'] = $result['root'] . '/' . $root_modifier; - } - } - // Poor man's realpath: take out the /../ with preg_replace. - // (realpath fails if the files in the path do not exist) - while(strpos($result['root'], '/../') !== FALSE) { - $result['root'] = preg_replace('/\w+\/\.\.\//', '', $result['root']); - } - - // TODO: Should we allow the uri to be transformed? - // I think that if the uri does not match, then you should - // always build the list by hand, and not rely on '_drush_sitealias_derive_record'. - - return $result; -} - -/** - * Convert from an alias record to a site specification - * - * @param alias_record - * The full alias record to convert - * - * @param with_db - * True if the site specification should include a ?db-url term - * - * @return string - * The site specification - */ -function drush_sitealias_alias_record_to_spec($alias_record, $with_db = false) { - $result = ''; - - // TODO: we should handle 'site-list' records too. - if (array_key_exists('site-list', $alias_record)) { - // TODO: we should actually expand the site list and recompose it - $result = implode(',', $alias_record['site-list']); - } - else { - // There should always be a uri - if (array_key_exists('uri', $alias_record)) { - $result = '#' . drush_sitealias_uri_to_site_dir($alias_record['uri'], drush_sitealias_get_root($alias_record)); - } - // There should always be a root - if (array_key_exists('root', $alias_record)) { - $result = $alias_record['root'] . $result; - } - if (array_key_exists('remote-host', $alias_record)) { - $result = drush_remote_host($alias_record) . $result; - } - - // Add the database info to the specification if desired - if ($with_db) { - // If db-url is not supplied, look it up from the remote - // or local site and add it to the site alias - if (!isset($alias_record['db-url'])) { - drush_sitealias_add_db_url($alias_record); - } - $result = $result . '?db-url=' . urlencode(is_array($alias_record['db-url']) ? $alias_record['db-url']['default'] : $alias_record['db-url']); - } - } - - return $result; -} - -/** - * Search for drupal installations in the search path. - * - * @param search_path - * An array of drupal root folders - * - * @return - * An array of site specifications (/path/to/root#sitename.com) - */ -function _drush_sitealias_find_local_sites($search_path) { - $result = array(); - foreach ($search_path as $a_drupal_root) { - $result = array_merge($result, _drush_find_local_sites_at_root($a_drupal_root)); - } - return $result; -} - -/** - * Return a list of all of the local sites at the specified drupal root. - */ -function _drush_find_local_sites_at_root($a_drupal_root = '', $search_depth = 1) { - $site_list = array(); - $base_path = (empty($a_drupal_root) ? drush_get_context('DRUSH_DRUPAL_ROOT') : $a_drupal_root ); - if (!empty($base_path)) { - if (drush_valid_root($base_path)) { - // If $a_drupal_root is in fact a valid drupal root, then return - // all of the sites found inside the 'sites' folder of this drupal instance. - $site_list = _drush_find_local_sites_in_sites_folder($base_path); - } - else { - $bootstrap_files = drush_scan_directory($base_path, '/' . basename(DRUSH_DRUPAL_SIGNATURE) . '/' , array('.', '..', 'CVS', 'examples'), 0, drush_get_option('search-depth', $search_depth) + 1, 'filename', 1); - foreach ($bootstrap_files as $one_bootstrap => $info) { - $includes_dir = dirname($one_bootstrap); - if (basename($includes_dir) == basename(dirname(DRUSH_DRUPAL_SIGNATURE))) { - $drupal_root = dirname($includes_dir); - $site_list = array_merge(_drush_find_local_sites_in_sites_folder($drupal_root), $site_list); - } - } - } - } - return $site_list; -} - -/** - * Return a list of all of the local sites at the specified 'sites' folder. - */ -function _drush_find_local_sites_in_sites_folder($a_drupal_root) { - $site_list = array(); - - // If anyone searches for sites at a given root, then - // make sure that alias files stored at this root - // directory are included in the alias search path - drush_sitealias_add_to_alias_path($a_drupal_root); - - $base_path = $a_drupal_root . '/sites'; - - // TODO: build a cache keyed off of $base_path (realpath($base_path)?), - // so that it is guarenteed that the lists returned will definitely be - // exactly the same should this routine be called twice with the same path. - - $files = drush_scan_directory($base_path, '/settings\.php/', array('.', '..', 'CVS', 'all'), 0, 1, 'filename', 1); - foreach ($files as $filename => $info) { - if ($info->basename == 'settings.php') { - // First we'll resolve the realpath of the settings.php file, - // so that we get the correct drupal root when symlinks are in use. - $real_sitedir = dirname(realpath($filename)); - $real_root = drush_locate_root($filename); - if ($real_root !== FALSE) { - $a_drupal_site = $real_root . '#' . basename($real_sitedir); - } - // If the symlink points to some folder outside of any drupal - // root, then we'll use the - else { - $uri = drush_sitealias_site_dir_from_filename($filename); - $a_drupal_site = $a_drupal_root . '#' . $uri; - } - // Add the site if it isn't already in the array - if (!in_array($a_drupal_site, $site_list)) { - $site_list[] = $a_drupal_site; - } - } - } - return $site_list; -} - -function drush_sitealias_create_sites_alias($a_drupal_root = '') { - $sites_list = _drush_find_local_sites_at_root($a_drupal_root); - _drush_sitealias_cache_alias('@sites', array('site-list' => $sites_list)); -} - -/** - * Add "transient" default values to the given alias record. The - * difference between a static default and a transient default is - * that static defaults -always- exist in the alias record, - * whereas transient defaults are only added if the given drush - * command explicitly calls this function. The other advantage - * of transient defaults is that it is possible to differentiate - * between a default value and an unspecified value, since the - * transient defaults are not added until requested. - * - * Since transient defaults are not cached, you should avoid doing - * expensive operations here. To be safe, drush commands should - * avoid calling this function more than once. - * - * @param alias_record - * An alias record with most values already filled in - */ -function _drush_sitealias_add_transient_defaults(&$alias_record) { - if (isset($alias_record['path-aliases'])) { - // Add the path to the drush folder to the path aliases as !drush - if (!array_key_exists('%drush', $alias_record['path-aliases'])) { - if (array_key_exists('%drush-script', $alias_record['path-aliases'])) { - $alias_record['path-aliases']['%drush'] = dirname($alias_record['path-aliases']['%drush-script']); - } - else { - $alias_record['path-aliases']['%drush'] = dirname(drush_find_drush()); - } - } - // Add the path to the site folder to the path aliases as !site - if (!array_key_exists('%site', $alias_record['path-aliases']) && array_key_exists('uri', $alias_record)) { - $alias_record['path-aliases']['%site'] = 'sites/' . drush_sitealias_uri_to_site_dir($alias_record['uri'], drush_sitealias_get_root($alias_record)) . '/'; - } - } -} - -/** - * Find the name of a local alias record that has the specified - * root and uri. - */ -function _drush_sitealias_find_local_alias_name($root, $uri) { - $result = ''; - $all_site_aliases =& drush_get_context('site-aliases'); - - foreach ($all_site_aliases as $alias_name => $alias_values) { - if (!array_key_exists('remote-host', $alias_values) && array_key_exists('root', $alias_values) && array_key_exists('uri', $alias_values) && ($alias_name != '@self')) { - if (($root == $alias_values['root']) && ($uri == $alias_values['uri'])) { - $result = $alias_name; - } - } - } - - return $result; -} - -/** - * If '$alias' is the name of a folder in the sites folder of the given drupal - * root, then build an alias record for it - * - * @param alias - * The name of the site in the 'sites' folder to convert - * @return array - * An alias record, or empty if none found. - */ -function _drush_sitealias_find_record_for_local_site($alias, $drupal_root = NULL) { - $alias_record = array(); - - // Clip off the leading '#' if it is there - if (substr($alias,0,1) == '#') { - $alias = substr($alias,1); - } - - if (!isset($drupal_root)) { - $drupal_root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT'); - } - - if (!empty($drupal_root)) { - $alias_dir = drush_sitealias_uri_to_site_dir($alias, $drupal_root); - $site_settings_file = $drupal_root . '/sites/' . $alias_dir . '/settings.php'; - $alias_record = drush_sitealias_build_record_from_settings_file($site_settings_file, $alias, $drupal_root); - } - - return $alias_record; -} - -function drush_sitealias_build_record_from_settings_file($site_settings_file, $alias = null, $drupal_root = null) { - $alias_record = array(); - - if (file_exists($site_settings_file)) { - if (!isset($drupal_root)) { - $drupal_root = drush_locate_root($site_settings_file); - } - - $alias_record['root'] = $drupal_root; - if (isset($alias)) { - $alias_record['uri'] = $alias; - } - else { - $alias_record['uri'] = _drush_sitealias_site_dir_to_uri(drush_sitealias_site_dir_from_filename($site_settings_file)); - } - } - - return $alias_record; -} - -/** - * Pull the site directory from the path to settings.php - * - * @param site_settings_file - * path to settings.php - * - * @return string - * the site directory component of the path to settings.php - */ -function drush_sitealias_site_dir_from_filename($site_settings_file) { - return basename(dirname($site_settings_file)); -} - -/** - * Convert from a URI to a site directory. - * - * @param uri - * A uri, such as http://domain.com:8080/drupal - * @return string - * A directory, such as domain.com.8080.drupal - */ -function drush_sitealias_uri_to_site_dir($uri, $site_root = NULL) { - $uri = str_replace('http://', '', $uri); - $uri = str_replace('https://', '', $uri); - if (drush_is_windows()) { - // Handle absolute paths on windows - $uri = str_replace(array(':/', ':\\'), array('.', '.'), $uri); - } - - $hostname = str_replace(array('/', ':', '\\'), array('.', '.', '.'), $uri); - - // Check sites.php mappings - $site_dir = drush_site_dir_lookup_from_hostname($hostname, $site_root); - - return $site_dir ? $site_dir : $hostname; -} - -/** - * Convert from an old-style database URL to an array of database settings. - * - * @param db_url - * A Drupal 6 db url string to convert, or an array with a 'default' element. - * @return array - * An array of database values containing only the 'default' element of - * the db url. If the parse fails the array is empty. - */ -function drush_convert_db_from_db_url($db_url) { - $db_spec = array(); - - if (is_array($db_url)) { - $db_url_default = $db_url['default']; - } - else { - $db_url_default = $db_url; - } - - // If it's a sqlite database, pick the database path and we're done. - if (strpos($db_url_default, 'sqlite://') === 0) { - $db_spec = array( - 'driver' => 'sqlite', - 'database' => substr($db_url_default, strlen('sqlite://')), - ); - } - else { - $url = parse_url($db_url_default); - if ($url) { - // Fill in defaults to prevent notices. - $url += array( - 'scheme' => NULL, - 'user' => NULL, - 'pass' => NULL, - 'host' => NULL, - 'port' => NULL, - 'path' => NULL, - ); - $url = (object)array_map('urldecode', $url); - $db_spec = array( - 'driver' => $url->scheme == 'mysqli' ? 'mysql' : $url->scheme, - 'username' => $url->user, - 'password' => $url->pass, - 'host' => $url->host, - 'port' => $url->port, - 'database' => ltrim($url->path, '/'), - ); - } - } - - return $db_spec; -} - -/** - * Convert from an old-style database URL to an array of database settings - * - * @param db_url - * A Drupal 6 db-url string to convert, or an array with multiple db-urls. - * @return array - * An array of database values. - */ -function drush_sitealias_convert_db_from_db_url($db_url) { - $result = array(); - - if (!is_array($db_url)) { - $result = array('default' => array('default' => drush_convert_db_from_db_url($db_url))); - } - else { - foreach ($db_url as $one_name => $one_db_url) { - $result[$one_name] = array('default' => drush_convert_db_from_db_url($one_db_url)); - } - } - - return $result; -} - -/** - * Utility function used by drush_get_alias; keys that start with - * '%' or '!' are path aliases, the rest are entries in the alias record. - */ -function _drush_sitealias_set_record_element(&$alias_record, $key, $value) { - if ((substr($key,0,1) == '%') || (substr($key,0,1) == '!')) { - $alias_record['path-aliases'][$key] = $value; - } - elseif (!empty($key)) { - $alias_record[$key] = $value; - } -} - -/** - * Looks up the specified alias record and calls through to - * drush_sitealias_set_alias_context, below. - * - * @param alias - * The name of the alias record - * @param prefix - * The prefix value to afix to the beginning of every - * key set. - * @return boolean - * TRUE is an alias was found and processed. - */ -function _drush_sitealias_set_context_by_name($alias, $prefix = '') { - if ($alias) { - $site_alias_settings = drush_sitealias_get_record($alias); - if (!empty($site_alias_settings)) { - drush_sitealias_set_alias_context($site_alias_settings, $prefix); - drush_sitealias_cache_alias_by_path($site_alias_settings); - if (empty($prefix)) { - - // Create an alias '@self' - // Allow 'uri' from the commandline to override - $drush_uri = drush_get_option(array('uri', 'l'), FALSE); - if ($drush_uri) { - $site_alias_settings['uri'] = $drush_uri; - } - - _drush_sitealias_cache_alias('@self', $site_alias_settings); - // Change the selected site to match the new --root and --uri, if any were set. - _drush_preflight_root_uri(); - } - return $site_alias_settings; - } - } - return array(); -} - -/** - * Given an alias record, overwrite its values with options - * from the command line and other drush contexts as specified - * by the provided prefix. For example, if the prefix is 'source-', - * then any option 'source-foo' will set the value 'foo' in the - * alias record. - */ -function drush_sitealias_overlay_options($site_alias_record, $prefix) { - return array_merge($site_alias_record, drush_get_merged_prefixed_options($prefix)); -} - -/** - * First return an option set via drush_sitealias_overlay_options, if - * any, then fall back on "%" . $option from the path aliases. - */ -function drush_sitealias_get_path_option($site_alias_record, $option, $default = NULL) { - if (isset($site_alias_record) && array_key_exists($option, $site_alias_record)) { - return $site_alias_record[$option]; - } - if (isset($site_alias_record) && array_key_exists('path-aliases', $site_alias_record) && array_key_exists("%$option", $site_alias_record['path-aliases'])) { - return $site_alias_record['path-aliases']["%$option"]; - } - else { - return drush_get_option($option, $default); - } -} - -/** - * Given a site alias record, copy selected fields from it - * into the drush 'alias' context. The 'alias' context has - * lower precedence than the 'cli' context, so values - * set by an alias record can be overridden by command-line - * parameters. - * - * @param site_alias_settings - * An alias record - * @param prefix - * The prefix value to affix to the beginning of every - * key set. For example, if this function is called once with - * 'source-' and again with 'destination-' prefixes, then the - * source database records will be stored in 'source-databases', - * and the destination database records will be in - * 'destination-databases'. - */ -function drush_sitealias_set_alias_context($site_alias_settings, $prefix = '') { - $options = drush_get_context('alias'); - - // There are some items that we should just skip - $skip_list = drush_get_special_keys(); - // If 'php-options' are set in the alias, then we will force drush - // to redispatch via the remote dispatch mechanism even if the target is localhost. - if ((array_key_exists('php-options', $site_alias_settings) || array_key_exists('php', $site_alias_settings)) && !drush_get_context('DRUSH_BACKEND', FALSE)) { - if (!array_key_exists('remote-host', $site_alias_settings)) { - $site_alias_settings['remote-host'] = 'localhost'; - } - } - // If 'php-options' are not set in the alias, then skip 'remote-host' - // and 'remote-user' if 'remote-host' is actually the local machine. - // This prevents drush from using the remote dispatch mechanism (the command - // is just run directly on the local machine, bootstrapping to the specified alias) - elseif (array_key_exists('remote-host', $site_alias_settings) && drush_is_local_host($site_alias_settings['remote-host'])) { - $skip_list[] = 'remote-host'; - $skip_list[] = 'remote-user'; - } - // If prefix is set, then copy from the 'prefix-' version - // of the drush special keys ('command-specific', 'path-aliases') - // into the ordinary version. This will allow us to set - // 'source-command-specific' options that will only apply when - // the alias is used as the source option for rsync or sql-sync. - if (!empty($prefix)) { - $special_contexts = drush_get_special_keys(); - foreach ($special_contexts as $option_name) { - if (array_key_exists($prefix . $option_name, $site_alias_settings)) { - $site_alias_settings[$option_name] = array_key_exists($option_name, $site_alias_settings) ? array_merge($site_alias_settings[$option_name], $site_alias_settings[$prefix . $option_name]) : $site_alias_settings[$prefix . $option_name]; - } - } - } - // Transfer all options from the site alias to the drush options - // in the 'alias' context. - foreach ($site_alias_settings as $key => $value) { - // Special handling for path aliases: - if ($key == "path-aliases") { - $path_aliases = $value; - foreach (array('%drush-script', '%dump', '%dump-dir', '%include') as $path_key) { - if (array_key_exists($path_key, $path_aliases)) { - // Evaluate the path value, and substitute any path references found. - // ex: '%dump-dir' => '%root/dumps' will store sql-dumps in the folder - // 'dumps' in the Drupal root folder for the site. - $evaluated_path = str_replace(array_keys($path_aliases), array_values($path_aliases), $path_aliases[$path_key]); - $options[$prefix . substr($path_key, 1)] = $evaluated_path; - } - } - } - // Special handling for command-specific - elseif ($key == "command-specific") { - $options[$key] = $value; - } - elseif (!in_array($key, $skip_list)) { - $options[$prefix . $key] = $value; - } - } - drush_set_config_options('alias', $options); -} - -/** - * Call prior to drush_sitealias_evaluate_path to insure - * that any site-specific aliases associated with any - * local site in $path are defined. - */ -function _drush_sitealias_preflight_path($path) { - $alias = NULL; - // Parse site aliases if there is a colon in the path - // We allow: - // @alias:/path - // machine.domain.com:/path - // machine:/path - // Note that paths in the form "c:/path" are converted to - // "/cygdrive/c/path" later; we do not want them to confuse - // us here, so we skip paths that start with a single character - // before the colon if we are running on Windows. Single-character - // machine names are allowed in Linux only. - $colon_pos = strpos($path, ':'); - if ($colon_pos > (drush_is_windows("LOCAL") ? 1 : 0)) { - $alias = substr($path, 0, $colon_pos); - $path = substr($path, $colon_pos + 1); - $site_alias_settings = drush_sitealias_get_record($alias); - if (empty($site_alias_settings) && (substr($path,0,1) == '@')) { - return NULL; - } - $machine = $alias; - } - else { - $machine = ''; - // if the path is a site alias or a local site... - $site_alias_settings = drush_sitealias_get_record($path); - if (empty($site_alias_settings) && (substr($path,0,1) == '@')) { - return NULL; - } - if (!empty($site_alias_settings) || drush_is_local_host($path)) { - $alias = $path; - $path = ''; - } - } - return array('alias' => $alias, 'path' => $path, 'machine' => $machine); -} - -/** - * Given a properly-escaped options string, replace any occurance of - * %files and so on embedded inside it with its corresponding path. - */ -function drush_sitealias_evaluate_paths_in_options($option_string) { - $path_aliases = _core_path_aliases(); - return str_replace(array_keys($path_aliases), array_values($path_aliases), $option_string); -} - -/** - * Evaluate a path from its shorthand form to a literal path - * usable by rsync. - * - * A path is "machine:/path" or "machine:path" or "/path" or "path". - * 'machine' might instead be an alias record, or the name - * of a site in the 'sites' folder. 'path' might be (or contain) - * '%root' or some other path alias. This function will examine - * all components of the path and evaluate them as necessary to - * come to the final path. - * - * @param path - * The path to evaluate - * @param additional_options - * An array of options that overrides whatever was passed in on - * the command line (like the 'process' context, but only for - * the scope of this one call). - * @param local_only - * If TRUE, force an error if the provided path points to a remote - * machine. - * @param os - * This should be the local system os, unless evaluate path is - * being called for rsync, in which case it should be "CWRSYNC" - * if cwrsync is being used, or "rsync" to automatically select - * between "LOCAL" and "CWRSYNC" based on the platform. - * @return - * The site record for the machine specified in the path, if any, - * with the path to pass to rsync (including the machine specifier) - * in the 'evaluated-path' item. - */ -function drush_sitealias_evaluate_path($path, &$additional_options, $local_only = FALSE, $os = NULL, $command_specific_prefix = '') { - $site_alias_settings = array(); - $path_aliases = array(); - $remote_user = ''; - - $preflight = _drush_sitealias_preflight_path($path); - if (!isset($preflight)) { - return NULL; - } - - $alias = $preflight['alias']; - $path = $preflight['path']; - $machine = $preflight['machine']; - - if (isset($alias)) { - // Note that the alias settings may have an 'os' component, but we do - // not want to use it here. The paths passed to rsync should always be - // escaped per the LOCAL rules, without regard to the remote platform type. - $site_alias_settings = drush_sitealias_get_record($alias); - if (!empty($command_specific_prefix)) { - drush_command_set_command_specific_options($command_specific_prefix); - drush_sitealias_command_default_options($site_alias_settings, $command_specific_prefix); - } - } - - if (!empty($site_alias_settings)) { - if ($local_only && array_key_exists('remote-host', $site_alias_settings)) { - return drush_set_error('DRUSH_REMOTE_SITE_IN_LOCAL_CONTEXT', dt("A remote site alias was used in a context where only a local alias is appropriate.")); - } - - // Apply any options from this alias that might affect our rsync - drush_sitealias_set_alias_context($site_alias_settings); - - // Use 'remote-host' from settings if available; otherwise site is local - if (drush_sitealias_is_remote_site($site_alias_settings)) { - $machine = drush_remote_host($site_alias_settings); - } - else { - $machine = ''; - } - } - else { - // Strip the machine portion of the path if the - // alias points to the local machine. - if (drush_is_local_host($machine)) { - $machine = ''; - } - else { - $machine = "$remote_user$machine"; - } - } - - // TOD: The code below is a little rube-goldberg-ish, and needs to be - // reworked. core-rsync will call this function twice: once to - // evaluate the destination, and then again to evaluate the source. Things - // get odd with --exclude-paths, especially in conjunction with command-specific - // and the --exclude-files option. @see testCommandSpecific() - - // If the --exclude-other-sites option is specified, then - // convert that into --include-paths='%site' and --exclude-sites. - if (drush_get_option_override($additional_options, 'exclude-other-sites', FALSE) && !drush_get_context('exclude-other-sites-processed', FALSE)) { - $include_path_option = drush_get_option_override($additional_options, 'include-paths', ''); - $additional_options['include-paths'] = '%site'; - if (!empty($include_path_option)) { - // We use PATH_SEPARATOR here because we are later going to explicitly explode() this variable using PATH_SEPARATOR. - $additional_options['include-paths'] .= PATH_SEPARATOR . $include_path_option; - } - $additional_options['exclude-sites'] = TRUE; - drush_set_context('exclude-other-sites-processed', TRUE); - } - else { - unset($additional_options['include-paths']); - } - // If the --exclude-files option is specified, then - // convert that into --exclude-paths='%files'. - if (drush_get_option_override($additional_options, 'exclude-files', FALSE) && !drush_get_option_override($additional_options, 'exclude-files-processed', FALSE, 'process')) { - $exclude_path_option = drush_get_option_override($additional_options, 'exclude-paths', ''); - $additional_options['exclude-paths'] = '%files'; - if (!empty($exclude_path_option)) { - // We use PATH_SEPARATOR here because we are later going to explicitly explode() this variable using PATH_SEPARATOR. - $additional_options['exclude-paths'] .= PATH_SEPARATOR . $exclude_path_option; - } - $additional_options['exclude-files-processed'] = TRUE; - } - else { - unset($additional_options['exclude-paths']); - } - - // If there was no site specification given, and the - // machine is local, then try to look - // up an alias record for the default drush site. - if (empty($site_alias_settings) && empty($machine)) { - $drush_uri = drush_get_context('DRUSH_SELECTED_URI', 'default'); - $site_alias_settings = drush_sitealias_get_record($drush_uri); - } - - // Always add transient defaults - _drush_sitealias_add_transient_defaults($site_alias_settings); - - // The $resolve_path variable is used by drush_sitealias_resolve_path_references - // to test to see if there are any path references such as %site or %files - // in it, so that resolution is only done if the path alias is referenced. - // Therefore, we can concatenate without worrying too much about the structure of - // this variable's contents. - $include_path = drush_get_option_override($additional_options, 'include-paths', ''); - $exclude_path = drush_get_option_override($additional_options, 'exclude-paths', ''); - if (is_array($include_path)) { - $include_path = implode('/', $include_path); - } - if (is_array($exclude_path)) { - $include_path = implode('/', $exclude_path); - } - $resolve_path = "$path/$include_path/$exclude_path"; - // Resolve path aliases such as %files, if any exist in the path - if (!empty($resolve_path)) { - drush_sitealias_resolve_path_references($site_alias_settings, $resolve_path); - } - - if (array_key_exists('path-aliases', $site_alias_settings)) { - $path_aliases = $site_alias_settings['path-aliases']; - } - - // Get the 'root' setting from the alias; if it does not - // exist, then get the root from the bootstrapped site. - if (array_key_exists('root', $site_alias_settings)) { - $drupal_root = $site_alias_settings['root']; - } - elseif (!drush_sitealias_is_remote_site($site_alias_settings)) { - drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_SITE); - $drupal_root = drush_get_context('DRUSH_DRUPAL_ROOT'); - } - if (empty($drupal_root)) { - $drupal_root = ''; - } - else { - // Add a slash to the end of the drupal root, as below. - $drupal_root = drush_trim_path($drupal_root) . "/"; - } - $full_path_aliases = $path_aliases; - foreach ($full_path_aliases as $key => $value) { - // Expand all relative path aliases to be based off of the Drupal root - if (!drush_is_absolute_path($value, "LOCAL") && ($key != '%root')) { - $full_path_aliases[$key] = $drupal_root . $value; - } - // We do not want slashes on the end of our path aliases. - $full_path_aliases[$key] = drush_trim_path($full_path_aliases[$key]); - } - - // Fill in path aliases in the path, the include path and the exclude path. - $path = str_replace(array_keys($full_path_aliases), array_values($full_path_aliases), $path); - if (!empty($include_path)) { - drush_set_option('include-paths', str_replace(array_keys($path_aliases), array_values($path_aliases), $include_path)); - } - if (!empty($exclude_path)) { - drush_set_option('exclude-paths', str_replace(array_keys($path_aliases), array_values($path_aliases), $exclude_path)); - } - // Next make the rsync path, which includes the machine - // and path components together. - // First make empty paths or relative paths start from the drupal root. - if (empty($path) || (!drush_is_absolute_path($path, "LOCAL"))) { - $path = $drupal_root . $path; - } - // When calculating a path for use with rsync, we must correct - // absolute paths in the form c:\path when cwrsync is in use. - $path = drush_correct_absolute_path_for_exec($path, $os); - - // If there is a $machine component, to the path, then - // add it to the beginning - $evaluated_path = drush_escapeshellarg($path, $os); - if (!empty($machine)) { - $evaluated_path = $machine . ':' . $evaluated_path; - } - - // - // Add our result paths: - // - // evaluated-path: machine:/path - // server-component: machine - // path-component: :/path - // path: /path - // user-path: path (as specified in input parameter) - // - $site_alias_settings['evaluated-path'] = $evaluated_path; - if (!empty($machine)) { - $site_alias_settings['server-component'] = $machine; - } - $site_alias_settings['path-component'] = (!empty($path) ? ':' . $path : ''); - $site_alias_settings['path'] = $path; - $site_alias_settings['user-path'] = $preflight['path']; - - return $site_alias_settings; -} - -/** - * Option keys used for site selection. - */ -function drush_sitealias_site_selection_keys() { - return array('remote-host', 'remote-user', 'ssh-options', '#name', 'os'); -} - - -function sitealias_find_local_drupal_root($site_list) { - $drupal_root = NULL; - - foreach ($site_list as $site) { - if (($drupal_root == NULL) && (array_key_exists('root', $site) && !array_key_exists('remote-host', $site))) { - $drupal_root = $site['root']; - } - } - - return $drupal_root; -} - - -/** - * Helper function to obtain the keys' names that need special handling in certain - * cases. - * @return - * A non-associative array containing the needed keys' names. - */ -function drush_get_special_keys() { - $special_keys = array( - 'command-specific', - 'site-aliases', - ); - return $special_keys; -} - -/** - * Read the tmp file where the persistent site setting is stored. - * - * @return string - * A valid site specification. - */ -function drush_sitealias_site_get() { - if (($filename = drush_sitealias_get_envar_filename()) && file_exists($filename)) { - $site = file_get_contents($filename); - return $site; - } - else { - return FALSE; - } -} - -/** - * Un-set the currently use'd site alias. - */ -function drush_sitealias_site_clear() { - if ($filename = drush_sitealias_get_envar_filename()) { - return drush_delete_dir($filename); - } - return FALSE; -} - -/** - * Returns the filename for the file that stores the DRUPAL_SITE variable. - * - * @param string $filename_prefix - * An arbitrary string to prefix the filename with. - * - * @return string|false - * Returns the full path to temp file if possible, or FALSE if not. - */ -function drush_sitealias_get_envar_filename($filename_prefix = 'drush-drupal-site-') { - $shell_pid = getenv('DRUSH_SHELL_PID'); - if (!$shell_pid && function_exists('posix_getppid')) { - $shell_pid = posix_getppid(); - } - if (!$shell_pid) { - return FALSE; - } - - $tmp = getenv('TMPDIR') ? getenv('TMPDIR') : '/tmp'; - $username = drush_get_username(); - - return "{$tmp}/drush-env-{$username}/{$filename_prefix}" . $shell_pid; -} - -/** - * Cache the specified alias in the alias path cache. The - * alias path cache creates a lookup from the site folder - * (/path/to/drupal/sites/default) to the provided alias record. - * - * Only the name of the alias and the path to the file it - * is stored in is cached; when it is retrieved, it is - * loaded directly from the correct file. - */ -function drush_sitealias_cache_alias_by_path($alias_record) { - if (!isset($alias_record['remote-host']) && isset($alias_record['root']) && isset($alias_record['uri']) && isset($alias_record['#name']) && isset($alias_record['#file'])) { - $path = drush_sitealias_local_site_path($alias_record); - if ($path) { - $cid = drush_get_cid('alias-path-', array(), array($path)); - $alias_path_data = array( - '#name' => $alias_record['#name'], - '#file' => $alias_record['#file'], - ); - drush_cache_set($cid, $alias_path_data); - } - } -} - -/** - * Look for a defined alias that points to the specified - * site directory. The cache is tested first; if nothing - * is cached, then an exhaustive search is done for the - * specified site. If the exhaustive search returns a - * match, then it is cached. - * - * @param $path - * /path/to/drupal/sites/default - * @return - * An alias record for the provided path - */ -function drush_sitealias_lookup_alias_by_path($path, $allow_best_match=FALSE) { - $result = drush_sitealias_quick_lookup_cached_alias_by_path($path); - $fallback = array(); - if (empty($result)) { - $aliases = _drush_sitealias_find_and_load_all_aliases(); - foreach ($aliases as $name => $alias_record) { - if (!isset($alias_record['remote-host']) && isset($alias_record['root']) && isset($alias_record['uri']) && isset($alias_record['#name']) && isset($alias_record['#file'])) { - if ($path == drush_sitealias_local_site_path($alias_record)) { - $result = $alias_record; - break; - } - if (substr($path, 0, strlen($alias_record['root'])) == $alias_record['root']) { - $fallback = $alias_record; - } - } - } - } - if (empty($result) && $allow_best_match) { - $result = $fallback; - } - if (!empty($result)) { - _drush_sitealias_add_inherited_values_to_record($result); - drush_sitealias_cache_alias_by_path($result); - } - return $result; -} - -/** - * Look for a cached alias that points to the specified - * site directory. Nothing is returned if there is no - * matching cached alias. - * - * @param $path - * /path/to/drupal/sites/default - * @return - * An alias record for the provided path - */ -function drush_sitealias_quick_lookup_cached_alias_by_path($path) { - $alias_record = array(); - $cid = drush_get_cid('alias-path-', array(), array($path)); - $alias_path_cache = drush_cache_get($cid); - if (isset($alias_path_cache->data)) { - $alias_name = $alias_path_cache->data['#name']; - $alias_file = $alias_path_cache->data['#file']; - - $alias_record = _drush_sitealias_find_and_load_alias_from_file($alias_name, array($alias_file)); - _drush_sitealias_add_inherited_values_to_record($alias_record); - $alias_record['#name'] = $alias_name; - } - return $alias_record; -} - -/** - * Return the site root, if there is one in the record. - */ -function drush_sitealias_get_root($alias_record) { - return array_key_exists('root', $alias_record) ? $alias_record['root'] : NULL; -} - -/** - * Decide on which side to run a core-rsync. - * - * @param $source - * @param $destination - * @param $runner Where to run the rsync operation: 'destination', 'source', - * 'auto' ('destination' if both are remote, otherwise '@self') or FALSE (@self) - * @return mixed - */ -function drush_get_runner($source, $destination, $runner = FALSE) { - if (is_string($source)) { - $source = drush_sitealias_get_record($site); - } - if (is_string($destination)) { - $destination = drush_sitealias_get_record($destination); - } - - // If both sites are remote, and --runner=auto, then we'll use the destination site. - if (drush_sitealias_is_remote_site($source) && drush_sitealias_is_remote_site($destination)) { - if ($runner == 'auto') { - $runner = 'destination'; - } - } - - // If the user explicitly requests a remote site, then return the selected one. - if ($runner == 'destination') { - return "@" . $destination['#name']; - } - if ($runner == 'source') { - return "@" . $source['#name']; - } - - // Default to running rsync locally. When in doubt, local is best, because - // we can always resolve aliases here. - return '@self'; -}