Yaffs site version 1.1
[yaffs-website] / vendor / drush / drush / commands / core / sitealias.drush.inc
1 <?php
2
3 /**
4  * @file
5  *   Site alias commands. @see example.drushrc.php for details.
6  */
7
8 function sitealias_drush_help($section) {
9   switch ($section) {
10     case 'drush:site-alias':
11       return dt('Print an alias record.');
12   }
13 }
14
15 function sitealias_drush_command() {
16   $items = array();
17
18   $items['site-alias'] = array(
19     'callback' => 'drush_sitealias_print',
20     'description' => 'Print site alias records for all known site aliases and local sites.',
21     'bootstrap' => DRUSH_BOOTSTRAP_NONE,
22     'arguments' => array(
23       'site' => 'Site specification to print',
24     ),
25     'options' => array(
26       'with-db' => 'Include the databases structure in the full alias record.',
27       'with-db-url' => 'Include the short-form db-url in the full alias record.',
28       'no-db' => 'Do not include the database record in the full alias record (default).',
29       'with-optional' => 'Include optional default items.',
30       'alias-name' => 'For a single alias, set the name to use in the output.',
31       'local-only' => 'Only display sites that are available on the local system (remote-site not set, and Drupal root exists).',
32       'show-hidden' => 'Include hidden internal elements in site alias output',
33     ),
34     'outputformat' => array(
35       'default' => 'config',
36       'pipe-format' => 'var_export',
37       'variable-name' => 'aliases',
38       'hide-empty-fields' => TRUE,
39       'private-fields' => 'password',
40       'field-labels' => array('#name' => 'Name', 'root' => 'Root', 'uri' => 'URI', 'remote-host' => 'Host', 'remote-user' => 'User', 'remote-port' => 'Port', 'os' => 'OS', 'ssh-options' => 'SSH options', 'php' => 'PHP'),
41       'fields-default' => array('#name', 'root', 'uri', 'remote-host', 'remote-user'),
42       'field-mappings' => array('name' => '#name'),
43       'output-data-type' => 'format-table',
44     ),
45     'aliases' => array('sa'),
46     'examples' => array(
47       'drush site-alias' => 'List all alias records known to drush.',
48       'drush site-alias @dev' => 'Print an alias record for the alias \'dev\'.',
49       'drush @none site-alias' => 'Print only actual aliases; omit multisites from the local Drupal installation.',
50     ),
51     'topics' => array('docs-aliases'),
52   );
53   $items['site-set'] = array(
54     'description' => 'Set a site alias to work on that will persist for the current session.',
55     'bootstrap' => DRUSH_BOOTSTRAP_NONE,
56     'handle-remote-commands' => TRUE,
57     'arguments' => array(
58       'site' => 'Site specification to use, or "-" for previous site. Omit this argument to "unset"',
59     ),
60     'aliases' => array('use'),
61     'examples' => array(
62       'drush site-set @dev' => 'Set the current session to use the @dev alias.',
63       'drush site-set user@server/path/to/drupal#sitename' => 'Set the current session to use a remote site via site specification.',
64       'drush site-set /path/to/drupal#sitename' => 'Set the current session to use a local site via site specification.',
65       'drush site-set -' => 'Go back to the previously-set site (like `cd -`).',
66       'drush site-set' => 'Without an argument, any existing site becomes unset.',
67     ),
68   );
69   return $items;
70 }
71
72 /**
73  * Command argument complete callback.
74  *
75  * @return
76  *  Array of available site aliases.
77  */
78 function sitealias_site_alias_complete() {
79   return array('values' => array_keys(_drush_sitealias_all_list()));
80 }
81
82 /**
83  * Command argument complete callback.
84  *
85  * @return
86  *  Array of available site aliases.
87  */
88 function sitealias_site_set_complete() {
89   return array('values' => array_keys(_drush_sitealias_all_list()));
90 }
91
92 /**
93  * Return a list of all site aliases known to drush.
94  *
95  * The array key is the site alias name, and the array value
96  * is the site specification for the given alias.
97  */
98 function _drush_sitealias_alias_list() {
99   return drush_get_context('site-aliases');
100 }
101
102 /**
103  * Return a list of all of the local sites at the current drupal root.
104  *
105  * The array key is the site folder name, and the array value
106  * is the site specification for that site.
107  */
108 function _drush_sitealias_site_list() {
109   $site_list = array();
110   $base_path = drush_get_context('DRUSH_DRUPAL_ROOT');
111   if ($base_path) {
112     $base_path .= '/sites';
113     $files = drush_scan_directory($base_path, '/settings\.php/', array('.', '..', 'CVS', 'all'), 0, 1);
114     foreach ($files as $filename => $info) {
115       if ($info->basename == 'settings.php') {
116         $alias_record = drush_sitealias_build_record_from_settings_file($filename);
117         if (!empty($alias_record)) {
118           $site_list[drush_sitealias_uri_to_site_dir($alias_record['uri'])] = $alias_record;
119         }
120       }
121     }
122   }
123   return $site_list;
124 }
125
126 /**
127  * Return the list of all site aliases and all local sites.
128  */
129 function _drush_sitealias_all_list() {
130   drush_sitealias_load_all();
131   return array_merge(_drush_sitealias_alias_list(), _drush_sitealias_site_list());
132 }
133
134 /**
135  * Return the list of site aliases (remote or local) that the
136  * user specified on the command line.  If none were specified,
137  * then all are returned.
138  */
139 function _drush_sitealias_user_specified_list() {
140   $command = drush_get_command();
141   $specifications = $command['arguments'];
142   $site_list = array();
143
144   // Iterate over the arguments and convert them to alias records
145   if (!empty($specifications)) {
146     list($site_list, $not_found) = drush_sitealias_resolve_sitespecs($specifications);
147     if (!empty($not_found)) {
148       return drush_set_error('DRUSH_ALIAS_NOT_FOUND', dt("Not found: @list", array("@list" => implode(', ', $not_found))));
149     }
150   }
151   // If the user provided no args, then we will return everything.
152   else {
153     drush_set_default_outputformat('list');
154     $site_list = _drush_sitealias_all_list();
155
156     // Filter out the hidden items
157     foreach ($site_list as $site_name => $one_site) {
158       if (array_key_exists('#hidden', $one_site)) {
159         unset($site_list[$site_name]);
160       }
161     }
162   }
163
164   // Filter for only local sites if specified.
165   if (drush_get_option('local-only', FALSE)) {
166     foreach ($site_list as $site_name => $one_site) {
167       if ( (array_key_exists('remote-site', $one_site)) ||
168            (!array_key_exists('root', $one_site)) ||
169            (!is_dir($one_site['root']))
170          ) {
171         unset($site_list[$site_name]);
172       }
173     }
174   }
175   return $site_list;
176 }
177
178 /**
179  * Print out the specified site aliases (or else all) using the format
180  * specified.
181  */
182 function drush_sitealias_print() {
183   // Try to get the @self alias to be defined.
184   $phase = drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_SITE);
185   $site_list = _drush_sitealias_user_specified_list();
186   if ($site_list === FALSE) {
187     return FALSE;
188   }
189   ksort($site_list);
190   $with_db = (drush_get_option('with-db') != NULL) || (drush_get_option('with-db-url') != NULL);
191
192   $site_specs = array();
193   foreach ($site_list as $site => $alias_record) {
194     $result_record = _drush_sitealias_prepare_record($alias_record);
195     $site_specs[$site] = $result_record;
196   }
197   ksort($site_specs);
198   return $site_specs;
199 }
200
201 /**
202  * Given a site alias name, print out a php-syntax
203  * representation of it.
204  *
205  * @param alias_record
206  *   The name of the site alias to print
207  */
208 function _drush_sitealias_prepare_record($alias_record) {
209   $output_db = drush_get_option('with-db');
210   $output_db_url = drush_get_option('with-db-url');
211   $output_optional_items = drush_get_option('with-optional');
212
213   // Make sure that the default items have been added for all aliases
214   _drush_sitealias_add_static_defaults($alias_record);
215
216   // Include the optional items, if requested
217   if ($output_optional_items) {
218     _drush_sitealias_add_transient_defaults($alias_record);
219   }
220
221   drush_sitealias_resolve_path_references($alias_record);
222
223   if (isset($output_db_url) || isset($output_db)) {
224     drush_sitealias_add_db_settings($alias_record);
225   }
226   // If the user specified --with-db-url, then leave the
227   // 'db-url' entry in the alias record (unless it is not
228   // set, in which case we will leave the 'databases' record instead).
229   if (isset($output_db_url)) {
230     if (!isset($alias_record['db-url'])) {
231       $alias_record['db-url'] = drush_sitealias_convert_databases_to_db_url($alias_record['databases']);
232     }
233     unset($alias_record['databases']);
234   }
235   // If the user specified --with-db, then leave the
236   // 'databases' entry in the alias record.
237   else if (isset($output_db)) {
238     unset($alias_record['db-url']);
239   }
240   // If neither --with-db nor --with-db-url were specified,
241   // then remove both the 'db-url' and the 'databases' entries.
242   else {
243     unset($alias_record['db-url']);
244     unset($alias_record['databases']);
245   }
246
247   // We don't want certain fields to go into the output
248   if (!drush_get_option('show-hidden')) {
249     foreach ($alias_record as $key => $value) {
250       if ($key[0] == '#') {
251         unset($alias_record[$key]);
252       }
253     }
254   }
255
256   // We only want to output the 'root' item; don't output the '%root' path alias
257   if (array_key_exists('path-aliases', $alias_record) && array_key_exists('%root', $alias_record['path-aliases'])) {
258     unset($alias_record['path-aliases']['%root']);
259     // If there is nothing left in path-aliases, then clear it out
260     if (count($alias_record['path-aliases']) == 0) {
261       unset($alias_record['path-aliases']);
262     }
263   }
264
265   return $alias_record;
266 }
267
268 function _drush_sitealias_print_record($alias_record, $site_alias = '') {
269   $result_record = _drush_sitealias_prepare_record($alias_record);
270
271   // The alias name will be the same as the site alias name,
272   // unless the user specified some other name on the command line.
273   $alias_name = drush_get_option('alias-name');
274   if (!isset($alias_name)) {
275     $alias_name = $site_alias;
276     if (empty($alias_name) || is_numeric($alias_name)) {
277       $alias_name = drush_sitealias_uri_to_site_dir($result_record['uri']);
278     }
279   }
280
281   // Alias names contain an '@' when referenced, but do
282   // not contain an '@' when defined.
283   if (substr($alias_name,0,1) == '@') {
284     $alias_name = substr($alias_name,1);
285   }
286
287   $exported_alias = var_export($result_record, TRUE);
288   drush_print('$aliases[\'' . $alias_name . '\'] = ' . $exported_alias . ';');
289 }
290
291 /**
292  * Use heuristics to attempt to convert from a site directory to a URI.
293  * This function should only be used when the URI really is unknown, as
294  * the mapping is not perfect.
295  *
296  * @param site_dir
297  *   A directory, such as domain.com.8080.drupal
298  *
299  * @return string
300  *   A uri, such as http://domain.com:8080/drupal
301  */
302 function _drush_sitealias_site_dir_to_uri($site_dir) {
303   // Protect IP addresses NN.NN.NN.NN by converting them
304   // temporarily to NN_NN_NN_NN for now.
305   $uri = preg_replace("/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/", "$1_$2_$3_$4", $site_dir);
306   // Convert .[0-9]+. into :[0-9]+/
307   $uri = preg_replace("/\.([0-9]+)\./", ":$1/", $uri);
308   // Convert .[0-9]$ into :[0-9]
309   $uri = preg_replace("/\.([0-9]+)$/", ":$1", $uri);
310   // Convert .(com|net|org|info). into .(com|net|org|info)/
311   $uri = str_replace(array('.com.', '.net.', '.org.', '.info.'), array('.com/', '.net/', '.org/', '.info/'), $uri);
312
313   // If there is a / then convert every . after the / to /
314   // Then again, if we did this we would break if the path contained a "."
315   // I hope that the path would never contain a "."...
316   $pos = strpos($uri, '/');
317   if ($pos !== false) {
318     $uri = substr($uri, 0, $pos + 1) . str_replace('.', '/', substr($uri, $pos + 1));
319   }
320
321   // n.b. this heuristic works all the time if there is a port,
322   // it also works all the time if there is a port and no path,
323   // but it does not work for domains such as .co.jp with no path,
324   // and it can fail horribly if someone makes a domain like "info.org".
325   // Still, I think this is the best we can do short of consulting DNS.
326
327   // Convert from NN_NN_NN_NN back to NN.NN.NN.NN
328   $uri = preg_replace("/([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)/", "$1.$2.$3.$4", $site_dir);
329
330   return 'http://' . $uri;
331 }
332
333 /**
334  * Validation callback for drush site-set.
335  */
336 function drush_sitealias_site_set_validate() {
337   if (!function_exists('posix_getppid')) {
338     $args = array('!command' => 'site-set', '!dependencies' => 'POSIX');
339     return drush_set_error('DRUSH_COMMAND_PHP_DEPENDENCY_ERROR', dt('Command !command needs the following PHP extensions installed/enabled to run: !dependencies.', $args));
340   }
341 }
342
343 /**
344  * Set the DRUPAL_SITE variable by writing it out to a temporary file that we
345  * then source for persistent site switching.
346  *
347  * @param site
348  *  A valid site specification.
349  */
350 function drush_sitealias_site_set($site = '@none') {
351   if ($filename = drush_sitealias_get_envar_filename()) {
352     $last_site_filename = drush_sitealias_get_envar_filename('drush-drupal-prev-site-');
353     if ($site == '-') {
354       if (file_exists($last_site_filename)) {
355         $site = file_get_contents($last_site_filename);
356       }
357       else {
358         $site = '@none';
359       }
360     }
361     if ($site == '@self') {
362       $path = drush_cwd();
363       $site_record = drush_sitealias_lookup_alias_by_path($path, TRUE);
364       if (isset($site_record['#name'])) {
365         $site = '@' . $site_record['#name'];
366       }
367       else {
368         $site = '@none';
369       }
370       // Using 'site-set @self' is quiet if there is no change.
371       $current = is_file($filename) ? trim(file_get_contents($filename)) : "@none";
372       if ($current == $site) {
373         return;
374       }
375     }
376     if (_drush_sitealias_set_context_by_name($site)) {
377       if (file_exists($filename)) {
378         @unlink($last_site_filename);
379         @rename($filename, $last_site_filename);
380       }
381       $success_message = dt("Site set to !site", array('!site' => $site));
382       if ($site == '@none') {
383         if (drush_delete_dir($filename)) {
384           drush_print($success_message);
385         }
386       }
387       elseif (drush_mkdir(dirname($filename), TRUE)) {
388         if (file_put_contents($filename, $site)) {
389           drush_print($success_message);
390           drush_log(dt("Site information stored in !file", array('!file' => $filename)));
391         }
392       }
393     }
394     else {
395       return drush_set_error('DRUPAL_SITE_NOT_FOUND', dt("Could not find a site definition for !site.", array('!site' => $site)));
396     }
397   }
398 }