2 namespace Consolidation\SiteAlias;
5 * Parse a string that contains a site specification.
7 * Site specifications contain some of the following elements:
11 * - uri (multisite selector)
16 * @var string Relative path from the site root to directory where
17 * multisite configuration directories are found.
19 protected $multisiteDirectoryRoot = 'sites';
22 * Parse a site specification
25 * A site specification in one of the accepted forms:
26 * - /path/to/drupal#uri
27 * - user@server/path/to/drupal#uri
28 * - user@server/path/to/drupal
33 * Drupal root (if provided).
35 * A site specification array with the specified components filled in:
40 * or, an empty array if the provided parameter is not a valid site spec.
42 public function parse($spec, $root = '')
44 $result = $this->match($spec);
45 return $this->fixAndCheckUsability($result, $root);
49 * Determine if the provided specification is valid. Note that this
50 * tests only for syntactic validity; to see if the specification is
51 * usable, call 'parse()', which will also filter out specifications
52 * for local sites that specify a multidev site that does not exist.
58 public function validSiteSpec($spec)
60 $result = $this->match($spec);
61 return !empty($result);
65 * Determine whether or not the provided name is an alias name.
67 * @param string $aliasName
70 public function isAliasName($aliasName)
72 return !empty($aliasName) && ($aliasName[0] == '@');
75 public function setMultisiteDirectoryRoot($location)
77 $this->multisiteDirectoryRoot = $location;
80 public function getMultisiteDirectoryRoot($root)
82 return $root . DIRECTORY_SEPARATOR . $this->multisiteDirectoryRoot;
86 * Return the set of regular expression patterns that match the available
87 * site specification formats.
90 * key: site specification regex
91 * value: an array mapping from site specification component names to
92 * the elements in the 'matches' array containing the data for that element.
94 protected function patterns()
96 $PATH = '([a-zA-Z]:[/\\\\][^#]*|[/\\\\][^#]*)';
97 $USER = '([a-zA-Z0-9\._-]+)';
98 $SERVER = '([a-zA-Z0-9\._-]+)';
99 $URI = '([a-zA-Z0-9_-]+)';
102 // /path/to/drupal#uri
103 "%^{$PATH}#{$URI}\$%" => [
107 // user@server/path/to/drupal#uri
108 "%^{$USER}@{$SERVER}{$PATH}#{$URI}\$%" => [
114 // user@server/path/to/drupal
115 "%^{$USER}@{$SERVER}{$PATH}\$%" => [
119 'uri' => 'default', // Or '2' if uri should be 'host'
122 "%^{$USER}@{$SERVER}#{$URI}\$%" => [
135 * Run through all of the available regex patterns and determine if
136 * any match the provided specification.
141 protected function match($spec)
143 foreach ($this->patterns() as $regex => $map) {
144 if (preg_match($regex, $spec, $matches)) {
145 return $this->mapResult($map, $matches);
152 * Inflate the provided array so that it always contains the required
158 protected function defaults($result = [])
169 * Take the data from the matches from the regular expression and
170 * plug them into the result array per the info in the provided map.
173 * An array mapping from result key to matches index.
174 * @param array $matches
175 * The matched strings returned from preg_match
179 protected function mapResult($map, $matches)
183 foreach ($map as $key => $index) {
184 $value = is_string($index) ? $index : $matches[$index];
185 $result[$key] = $value;
188 if (empty($result)) {
192 return $this->defaults($result);
196 * Validate the provided result. If the result is local, then it must
197 * have a 'root'. If it does not, then fill in the root that was provided
198 * to us in our consturctor.
200 * @param array $result
201 * @see parse() result.
205 protected function fixAndCheckUsability($result, $root)
207 if (empty($result) || !empty($result['host'])) {
211 if (empty($result['root'])) {
212 // TODO: should these throw an exception, so the user knows
213 // why their site spec was invalid?
214 if (empty($root) || !is_dir($root)) {
218 $result['root'] = $root;
221 // If using a sitespec `#uri`, then `uri` MUST
222 // be the name of a folder that exists in __DRUPAL_ROOT__/sites.
223 // This restriction does NOT apply to the --uri option. Are there
224 // instances where we need to allow 'uri' to be a literal uri
225 // rather than the folder name? If so, we need to loosen this check.
226 // I think it's fine as it is, though.
227 $path = $this->getMultisiteDirectoryRoot($result['root']) . DIRECTORY_SEPARATOR . $result['uri'];
228 if (!is_dir($path)) {