Files
drupal11-ddev/vendor/consolidation/site-alias/src/SiteAliasFileDiscovery.php
2025-10-08 11:39:17 -04:00

218 lines
6.0 KiB
PHP

<?php
namespace Consolidation\SiteAlias;
use Symfony\Component\Finder\Finder;
/**
* Discover alias files named:
*
* - sitename.site.yml: contains multiple aliases, one for each of the
* environments of 'sitename'.
*
* Drush aliases that contain both a site name and an environment
* (e.g. @site.env) will cause Drush to find the file named after
* the respective site name and retrieve the specified environment
* record.
*
* Sites may also define a special alias file self.site.yml, which
* may be stored in the drush/sites directory relative to either
* the Drupal root or the Composer root of the site. The environments
* in this file will be merged with the available environments for
* the element @self, however it is defined.
*/
class SiteAliasFileDiscovery
{
protected $searchLocations;
protected $locationFilter;
protected $depth;
public function __construct($searchLocations = [], $depth = '<= 1', $locationFilter = null)
{
// TODO: Change the default parameter value from 'null' to an empty string
if ($locationFilter === null) {
$locationFilter = '';
}
$this->locationFilter = $locationFilter;
$this->searchLocations = $searchLocations;
$this->depth = $depth;
}
/**
* Add a location that alias files may be found.
*
* @param string $path
* @return $this
*/
public function addSearchLocation($paths)
{
foreach ((array)$paths as $path) {
if (is_dir($path)) {
$this->searchLocations[] = $path;
}
}
return $this;
}
/**
* Return all of the paths where alias files may be found.
* @return string[]
*/
public function searchLocations()
{
return $this->searchLocations;
}
public function locationFilter()
{
return $this->locationFilter;
}
/**
* Set the search depth for finding alias files
*
* @param string|int $depth (@see \Symfony\Component\Finder\Finder::depth)
* @return $this
*/
public function depth($depth)
{
$this->depth = $depth;
return $this;
}
/**
* Only search for aliases that are in alias files stored in directories
* whose basename or key matches the specified location.
*/
public function filterByLocation($location)
{
if (empty($location)) {
return $this;
}
return new SiteAliasFileDiscovery($this->searchLocations(), $this->depth, $location);
}
/**
* Find an alias file SITENAME.site.yml in one
* of the specified search locations.
*
* @param string $siteName
* @return string[]
*/
public function find($siteName)
{
return $this->searchForAliasFiles("$siteName.site.yml");
}
/**
* Find an alias file SITENAME.site.yml in one
* of the specified search locations.
*
* @param string $siteName
* @return string|bool
*/
public function findSingleSiteAliasFile($siteName)
{
$matches = $this->find($siteName);
if (empty($matches)) {
return false;
}
return reset($matches);
}
/**
* Return a list of all SITENAME.site.yml files in any of
* the search locations.
*
* @return string[]
*/
public function findAllSingleAliasFiles()
{
return $this->searchForAliasFiles('*.site.yml');
}
/**
* Return all of the legacy alias files used in previous Drush versions.
*
* @return string[]
*/
public function findAllLegacyAliasFiles()
{
return array_merge(
$this->searchForAliasFiles('*.alias.drushrc.php'),
$this->searchForAliasFiles('*.aliases.drushrc.php'),
$this->searchForAliasFiles('aliases.drushrc.php')
);
}
/**
* Create a Symfony Finder object to search all available search locations
* for the specified search pattern.
*
* @param string $searchPattern
* @return Finder
*/
protected function createFinder($searchPattern)
{
$finder = new Finder();
$finder->files()
->name($searchPattern)
->in($this->searchLocations)
->depth($this->depth);
return $finder;
}
/**
* Return a list of all alias files matching the provided pattern.
*
* @param string $searchPattern
* @return string[]
*/
protected function searchForAliasFiles($searchPattern)
{
if (empty($this->searchLocations)) {
return [];
}
list($match, $site) = $this->splitLocationFromSite($this->locationFilter);
if (!empty($site)) {
$searchPattern = str_replace('*', $site, $searchPattern);
}
$finder = $this->createFinder($searchPattern);
$result = [];
foreach ($finder as $file) {
$path = $file->getRealPath();
$result[] = $path;
}
// Find every location where the parent directory name matches
// with the first part of the search pattern.
// In theory we can use $finder->path() instead. That didn't work well,
// in practice, though; had trouble correctly escaping the path separators.
if (!empty($this->locationFilter)) {
$result = array_filter($result, function ($path) use ($match) {
return SiteAliasName::locationFromPath($path) === $match;
});
}
return $result;
}
/**
* splitLocationFromSite returns the part of 'site' before the first
* '.' as the "path match" component, and the part after the first
* '.' as the "site" component.
*/
protected function splitLocationFromSite($site)
{
$parts = explode('.', $site, 3) + ['', '', ''];
return array_slice($parts, 0, 2);
}
// TODO: Seems like this could just be basename()
protected function extractKey($basename, $filenameExensions)
{
return str_replace($filenameExensions, '', $basename);
}
}