Yaffs site version 1.1
[yaffs-website] / vendor / drush / drush / commands / runserver / runserver.drush.inc
1 <?php
2
3 /**
4  * @file
5  * Built in http server commands.
6  */
7
8 /**
9  * Implements hook_drush_help().
10  */
11 function runserver_drush_help($section) {
12   switch ($section) {
13     case 'meta:runserver:title':
14       return dt("Runserver commands");
15     case 'meta:runserver:summary':
16       return dt('Launch the built-in PHP webserver.');
17     case 'drush:runserver':
18       return dt("Runs a lightweight built in http server for development.
19  - Don't use this for production, it is neither scalable nor secure for this use.
20  - If you run multiple servers simultaneously, you will need to assign each a unique port.
21  - Use Ctrl-C or equivalent to stop the server when complete.");
22   }
23 }
24
25 /**
26  * Implements hook_drush_command().
27  */
28 function runserver_drush_command() {
29   $items = array();
30
31   $items['runserver'] = array(
32     'description' => 'Runs PHP\'s built-in http server for development.',
33     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
34     'arguments' => array(
35       'addr:port/path' => 'Host IP address and port number to bind to and path to open in web browser. Format is addr:port/path, default 127.0.0.1:8888, all elements optional. See examples for shorthand. Only opens a browser if a path is specified.',
36     ),
37     'options' => array(
38       'variables' => 'Key-value array of variables to override in the $conf array for the running site. By default disables drupal_http_request_fails to avoid errors on Windows (which supports only one connection at a time). Comma delimited list of name=value pairs (or array in drushrc).',
39       'default-server' => 'A default addr:port/path to use for any values not specified as an argument.',
40       'user' => 'If opening a web browser, automatically log in as this user (user ID or username). Default is to log in as uid 1.',
41       'browser' => 'If opening a web browser, which browser to user (defaults to operating system default). Use --no-browser to avoid opening a browser.',
42       'dns' => 'Resolve hostnames/IPs using DNS/rDNS (if possible) to determine binding IPs and/or human friendly hostnames for URLs and browser.',
43     ),
44     'aliases' => array('rs'),
45     'examples' => array(
46       'drush rs 8080' => 'Start runserver on 127.0.0.1, port 8080.',
47       'drush rs 10.0.0.28:80' => 'Start runserver on 10.0.0.28, port 80.',
48       'drush rs [::1]:80' => 'Start runserver on IPv6 localhost ::1, port 80.',
49       'drush rs --dns localhost:8888/user' => 'Start runserver on localhost (using rDNS to determine binding IP), port 8888, and open /user in browser.',
50       'drush rs /' => 'Start runserver on default IP/port (127.0.0.1, port 8888), and open / in browser.',
51       'drush rs --default-server=127.0.0.1:8080/ -' => 'Use a default (would be specified in your drushrc) that starts runserver on port 8080, and opens a browser to the front page. Set path to a single hyphen path in argument to prevent opening browser for this session.',
52       'drush rs :9000/admin' => 'Start runserver on 127.0.0.1, port 9000, and open /admin in browser. Note that you need a colon when you specify port and path, but no IP.',
53     ),
54   );
55   return $items;
56 }
57
58 /**
59  * Callback for runserver command.
60  */
61 function drush_core_runserver($uri = NULL) {
62   global $user, $base_url;
63
64   // Determine active configuration.
65   $uri = runserver_uri($uri);
66   if (!$uri) {
67     return FALSE;
68   }
69
70   // Remove any leading slashes from the path, since that is what url() expects.
71   $path = ltrim($uri['path'], '/');
72
73   // $uri['addr'] is a special field set by runserver_uri()
74   $hostname = $uri['host'];
75   $addr = $uri['addr'];
76
77   drush_set_context('DRUSH_URI', 'http://' . $hostname . ':' . $uri['port']);
78
79   // We pass in the currently logged in user (if set via the --user option),
80   // which will automatically log this user in the browser during the first
81   // request.
82   if (drush_get_option('user', FALSE) === FALSE) {
83     drush_set_option('user', 1);
84   }
85   drush_bootstrap_max(DRUSH_BOOTSTRAP_DRUPAL_LOGIN);
86
87   // We delete any registered files here, since they are not caught by Ctrl-C.
88   _drush_delete_registered_files();
89
90   // We set the effective base_url, since we have now detected the current site,
91   // and need to ensure generated URLs point to our runserver host.
92   // We also pass in the effective base_url to our auto_prepend_script via the
93   // CGI environment. This allows Drupal to generate working URLs to this http
94   // server, whilst finding the correct multisite from the HTTP_HOST header.
95   $base_url = 'http://' . $addr . ':' . $uri['port'];
96   $env['RUNSERVER_BASE_URL'] = $base_url;
97
98   // We pass in an array of $conf overrides using the same approach.
99   // This is available as an option for developers to pass in their own
100   // favorite $conf overrides (e.g. disabling css aggregation).
101   $current_override = drush_get_option_list('variables', array());
102   $override = array();
103   foreach ($current_override as $name => $value) {
104     if (is_numeric($name) && (strpos($value, '=') !== FALSE)) {
105       list($name, $value) = explode('=', $value, 2);
106     }
107     $override[$name] = $value;
108   }
109   $env['RUNSERVER_CONF'] = urlencode(serialize($override));
110
111   // We log in with the specified user ID (if set) via the password reset URL.
112   $user_message = '';
113   $usersingle = drush_user_get_class()->getCurrentUserAsSingle();
114   if ($usersingle->id()) {
115     $browse = $usersingle->passResetUrl($path);
116     $user_message = ', logged in as ' . $usersingle->getUsername();
117   }
118   else {
119     $browse = drush_url($path);
120   }
121
122   drush_print(dt('HTTP server listening on !addr, port !port (see http://!hostname:!port/!path), serving site !site!user...', array('!addr' => $addr, '!hostname' => $hostname, '!port' => $uri['port'], '!path' => $path, '!site' => drush_get_context('DRUSH_DRUPAL_SITE', 'default'), '!user' => $user_message)));
123   // Start php 5.4 builtin server.
124   // Store data used by runserver-prepend.php in the shell environment.
125   foreach ($env as $key => $value) {
126     putenv($key . '=' . $value);
127   }
128   if (!empty($uri['path'])) {
129     // Start a browser if desired. Include a 2 second delay to allow the
130     // server to come up.
131     drush_start_browser($browse, 2);
132   }
133   // Start the server using 'php -S'.
134   if (drush_drupal_major_version() >= 8) {
135     $extra = ' "' . __DIR__ . '/d8-rs-router.php"';
136   }
137   elseif (drush_drupal_major_version() == 7) {
138     $extra = ' "' . __DIR__ . '/d7-rs-router.php"';
139   }
140   else {
141     $extra = ' --define auto_prepend_file="' . __DIR__ . '/runserver-prepend.php"';
142   }
143   $root = drush_get_context('DRUSH_SELECTED_DRUPAL_ROOT');
144   drush_shell_exec_interactive('cd %s && %s -S ' . $addr . ':' . $uri['port']. $extra, $root, drush_get_option('php', 'php'));
145 }
146
147 /**
148  * Determine the URI to use for this server.
149  */
150 function runserver_uri($uri) {
151   $drush_default = array(
152     'host' => '127.0.0.1',
153     'port' => '8888',
154     'path' => '',
155   );
156   $user_default = runserver_parse_uri(drush_get_option('default-server', ''));
157   $site_default = runserver_parse_uri(drush_get_option('uri', ''));
158   $uri = runserver_parse_uri($uri);
159   if (is_array($uri)) {
160     // Populate defaults.
161     $uri = $uri + $user_default + $site_default + $drush_default;
162     if (ltrim($uri['path'], '/') == '-') {
163       // Allow a path of a single hyphen to clear a default path.
164       $uri['path'] = '';
165     }
166     // Determine and set the new URI.
167     $uri['addr'] = $uri['host'];
168     if (drush_get_option('dns', FALSE)) {
169       if (ip2long($uri['host'])) {
170         $uri['host'] = gethostbyaddr($uri['host']);
171       }
172       else {
173         $uri['addr'] = gethostbyname($uri['host']);
174       }
175     }
176   }
177   return $uri;
178 }
179
180 /**
181  * Parse a URI or partial URI (including just a port, host IP or path).
182  *
183  * @param string $uri
184  *   String that can contain partial URI.
185  *
186  * @return array
187  *   URI array as returned by parse_url.
188  */
189 function runserver_parse_uri($uri) {
190   if (empty($uri)) {
191     return array();
192   }
193   if ($uri[0] == ':') {
194     // ':port/path' shorthand, insert a placeholder hostname to allow parsing.
195     $uri = 'placeholder-hostname' . $uri;
196   }
197   // FILTER_VALIDATE_IP expects '[' and ']' to be removed from IPv6 addresses.
198   // We check for colon from the right, since IPv6 addresses contain colons.
199   $to_path = trim(substr($uri, 0, strpos($uri, '/')), '[]');
200   $to_port = trim(substr($uri, 0, strrpos($uri, ':')), '[]');
201   if (filter_var(trim($uri, '[]'), FILTER_VALIDATE_IP) || filter_var($to_path, FILTER_VALIDATE_IP) || filter_var($to_port, FILTER_VALIDATE_IP)) {
202     // 'IP', 'IP/path' or 'IP:port' shorthand, insert a schema to allow parsing.
203     $uri = 'http://' . $uri;
204   }
205   $uri = parse_url($uri);
206   if (empty($uri)) {
207     return drush_set_error('RUNSERVER_INVALID_ADDRPORT', dt('Invalid argument - should be in the "host:port/path" format, numeric (port only) or non-numeric (path only).'));
208   }
209   if (count($uri) == 1 && isset($uri['path'])) {
210     if (is_numeric($uri['path'])) {
211       // Port only shorthand.
212       $uri['port'] = $uri['path'];
213       unset($uri['path']);
214     }
215   }
216   if (isset($uri['host']) && $uri['host'] == 'placeholder-hostname') {
217     unset($uri['host']);
218   }
219   return $uri;
220 }