2 namespace Drush\SiteAlias;
5 * Parse a string that contains a site specification.
7 * Site specifications contain some of the following elements:
11 * - uri (multisite selector)
16 * Parse a site specification
19 * A site specification in one of the accepted forms:
20 * - /path/to/drupal#uri
21 * - user@server/path/to/drupal#uri
22 * - user@server/path/to/drupal
27 * Drupal root (if provided).
29 * A site specification array with the specified components filled in:
34 * or, an empty array if the provided parameter is not a valid site spec.
36 public function parse($spec, $root = '')
38 $result = $this->match($spec);
39 return $this->fixAndCheckUsability($result, $root);
43 * Determine if the provided specification is valid. Note that this
44 * tests only for syntactic validity; to see if the specification is
45 * usable, call 'parse()', which will also filter out specifications
46 * for local sites that specify a multidev site that does not exist.
52 public function validSiteSpec($spec)
54 $result = $this->match($spec);
55 return !empty($result);
59 * Determine whether or not the provided name is an alias name.
61 * @param string $aliasName
64 public function isAliasName($aliasName)
66 return !empty($aliasName) && ($aliasName[0] == '@');
70 * Return the set of regular expression patterns that match the available
71 * site specification formats.
74 * key: site specification regex
75 * value: an array mapping from site specification component names to
76 * the elements in the 'matches' array containing the data for that element.
78 protected function patterns()
81 // /path/to/drupal#uri
82 '%^(/[^#]*)#([a-zA-Z0-9_-]+)$%' => [
86 // user@server/path/to/drupal#uri
87 '%^([a-zA-Z0-9_-]+)@([a-zA-Z0-9_-]+)(/[^#]*)#([a-zA-Z0-9_-]+)$%' => [
93 // user@server/path/to/drupal
94 '%^([a-zA-Z0-9_-]+)@([a-zA-Z0-9_-]+)(/[^#]*)$%' => [
98 'uri' => 'default', // Or '2' if uri should be 'host'
101 '%^([a-zA-Z0-9_-]+)@([a-zA-Z0-9_-]+)#([a-zA-Z0-9_-]+)$%' => [
107 '%^#([a-zA-Z0-9_-]+)$%' => [
114 * Run through all of the available regex patterns and determine if
115 * any match the provided specification.
120 protected function match($spec)
122 foreach ($this->patterns() as $regex => $map) {
123 if (preg_match($regex, $spec, $matches)) {
124 return $this->mapResult($map, $matches);
131 * Inflate the provided array so that it always contains the required
137 protected function defaults($result = [])
148 * Take the data from the matches from the regular expression and
149 * plug them into the result array per the info in the provided map.
152 * An array mapping from result key to matches index.
153 * @param array $matches
154 * The matched strings returned from preg_match
158 protected function mapResult($map, $matches)
162 foreach ($map as $key => $index) {
163 $value = is_string($index) ? $index : $matches[$index];
164 $result[$key] = $value;
167 if (empty($result)) {
171 return $this->defaults($result);
175 * Validate the provided result. If the result is local, then it must
176 * have a 'root'. If it does not, then fill in the root that was provided
177 * to us in our consturctor.
179 * @param array $result
180 * @see parse() result.
184 protected function fixAndCheckUsability($result, $root)
186 if (empty($result) || !empty($result['host'])) {
190 if (empty($result['root'])) {
191 // TODO: should these throw an exception, so the user knows
192 // why their site spec was invalid?
193 if (empty($root) || !is_dir($root)) {
197 $result['root'] = $root;
200 // TODO: If using a sitespec `#uri`, then `uri` MUST
201 // be the name of a folder that exists in __DRUPAL_ROOT__/sites.
202 // This restriction does NOT apply to the --uri option. Are there
203 // instances where we need to allow 'uri' to be a literal uri
204 // rather than the folder name? If so, we need to loosen this check.
205 // I think it's fine as it is, though.
206 $path = $result['root'] . '/sites/' . $result['uri'];
207 if (!is_dir($path)) {