X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fdrush%2Fdrush%2Fsrc%2FCommands%2Fcore%2FSiteInstallCommands.php;fp=vendor%2Fdrush%2Fdrush%2Fsrc%2FCommands%2Fcore%2FSiteInstallCommands.php;h=0b046d9967597bc1648b95846840a4c6789fb989;hp=0000000000000000000000000000000000000000;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0 diff --git a/vendor/drush/drush/src/Commands/core/SiteInstallCommands.php b/vendor/drush/drush/src/Commands/core/SiteInstallCommands.php new file mode 100644 index 000000000..0b046d996 --- /dev/null +++ b/vendor/drush/drush/src/Commands/core/SiteInstallCommands.php @@ -0,0 +1,406 @@ + self::REQ, 'db-prefix' => self::REQ, 'db-su' => self::REQ, 'db-su-pw' => self::REQ, 'account-name' => 'admin', 'account-mail' => 'admin@example.com', 'site-mail' => 'admin@example.com', 'account-pass' => self::REQ, 'locale' => 'en', 'site-name' => 'Drush Site-Install', 'site-pass' => self::REQ, 'sites-subdir' => self::REQ, 'config-dir' => self::REQ]) + { + $additional = $profile; + $profile = array_shift($additional) ?: ''; + $form_options = []; + foreach ((array)$additional as $arg) { + list($key, $value) = explode('=', $arg, 2); + + // Allow for numeric and NULL values to be passed in. + if (is_numeric($value)) { + $value = intval($value); + } elseif ($value == 'NULL') { + $value = null; + } + + $form_options[$key] = $value; + } + + $this->serverGlobals(Drush::bootstrapManager()->getUri()); + $class_loader = Drush::service('loader'); + $profile = $this->determineProfile($profile, $options, $class_loader); + + $sql = SqlBase::create($options); + $db_spec = $sql->getDbSpec(); + + $account_pass = $options['account-pass'] ?: StringUtils::generatePassword(); + $settings = [ + 'parameters' => [ + 'profile' => $profile, + 'langcode' => $options['locale'], + ], + 'forms' => [ + 'install_settings_form' => [ + 'driver' => $db_spec['driver'], + $db_spec['driver'] => $db_spec, + 'op' => dt('Save and continue'), + ], + 'install_configure_form' => [ + 'site_name' => $options['site-name'], + 'site_mail' => $options['site-mail'], + 'account' => [ + 'name' => $options['account-name'], + 'mail' => $options['account-mail'], + 'pass' => [ + 'pass1' => $account_pass, + 'pass2' => $account_pass, + ], + ], + 'enable_update_status_module' => true, + 'enable_update_status_emails' => true, + 'clean_url' => true, + 'op' => dt('Save and continue'), + ], + ], + ]; + + // Merge in the additional options. + foreach ($form_options as $key => $value) { + $current = &$settings['forms']; + foreach (explode('.', $key) as $param) { + $current = &$current[$param]; + } + $current = $value; + } + + $msg = 'Starting Drupal installation. This takes a while.'; + if (is_null($options['notify'])) { + $msg .= ' Consider using the --notify global option.'; + } + $this->logger()->notice(dt($msg)); + + // Define some functions which alter away the install_finished task. + require_once Path::join(DRUSH_BASE_PATH, 'includes/site_install.inc'); + + require_once DRUSH_DRUPAL_CORE . '/includes/install.core.inc'; + drush_op('install_drupal', $class_loader, $settings); + if (empty($options['account-pass'])) { + $this->logger()->success(dt('Installation complete. User name: @name User password: @pass', ['@name' => $options['account-name'], '@pass' => $account_pass])); + } else { + $this->logger()->success(dt('Installation complete.')); + } + } + + protected function determineProfile($profile, $options, $class_loader) + { + // --config-dir fails with Standard profile and any other one that carries content entities. + // Force to minimal install profile. + if ($options['config-dir']) { + $this->logger()->info(dt("Using 'minimal' install profile since --config-dir option was provided.")); + $profile = 'minimal'; + } + if (empty($profile)) { + $boot = Drush::bootstrap(); + $profile = $boot->getKernel()->getInstallProfile(); + } + + if (empty($profile)) { + // If there is an installation profile that acts as a distribution, use it. + // You can turn your installation profile into a distribution by providing a + // @code + // distribution: + // name: 'Distribution name' + // @endcode + // block in the profile's info YAML file. + // See https://www.drupal.org/node/2210443 for more information. + require_once DRUSH_DRUPAL_CORE . '/includes/install.core.inc'; + $install_state = ['interactive' => false] + install_state_defaults(); + try { + install_begin_request($class_loader, $install_state); + $profile = _install_select_profile($install_state); + } catch (\Exception $e) { + // This is only a best effort to provide a better default, no harm done + // if it fails. + } + } + if (empty($profile)) { + $profile = 'standard'; + } + return $profile; + } + + /** + * Post installation, run the configuration import. + * + * @hook post-command site-install + */ + public function post($result, CommandData $commandData) + { + if ($config = $commandData->input()->getOption('config-dir')) { + // Set the destination site UUID to match the source UUID, to bypass a core fail-safe. + $source_storage = new FileStorage($config); + $options = ['yes' => true]; + drush_invoke_process('@self', 'config-set', ['system.site', 'uuid', $source_storage->read('system.site')['uuid']], $options); + // Run a full configuration import. + drush_invoke_process('@self', 'config-import', [], ['source' => $config] + $options); + } + } + + /** + * Check to see if there are any .yml files in the provided config directory. + */ + protected function hasConfigFiles($config) + { + $files = glob("$config/*.yml"); + return !empty($files); + } + + /** + * @hook validate site-install + */ + public function validate(CommandData $commandData) + { + if ($sites_subdir = $commandData->input()->getOption('sites-subdir')) { + $lower = strtolower($sites_subdir); + if ($sites_subdir != $lower) { + $this->logger()->warning(dt('Only lowercase sites-subdir are valid. Switching to !lower.', ['!lower' => $lower])); + $commandData->input()->setOption('sites-subdir', $lower); + } + // Make sure that we will bootstrap to the 'sites-subdir' site. + $bootstrapManager = Drush::bootstrapManager(); + $bootstrapManager->setUri('http://' . $sites_subdir); + } + + if ($config = $commandData->input()->getOption('config-dir')) { + if (!file_exists($config)) { + throw new \Exception('The config source directory does not exist.'); + } + if (!is_dir($config)) { + throw new \Exception('The config source is not a directory.'); + } + // Skip config import with a warning if specified config dir is empty. + if (!$this->hasConfigFiles($config)) { + $this->logger()->warning(dt('Configuration import directory @config does not contain any configuration; will skip import.', ['@config' => $config])); + $commandData->input()->setOption('config-dir', ''); + } + } + + try { + // Get AnnotationData. @todo Find a better way. + $annotationData = Drush::getApplication()->find('site:install')->getAnnotationData(); + Drush::bootstrapManager()->bootstrapMax(DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION, $annotationData); + $sql = SqlBase::create($commandData->input()->getOptions()); + } catch (\Exception $e) { + // Ask questions to get our data. + // TODO: we should only 'ask' in hook interact, never in hook validate + if ($commandData->input()->getOption('db-url') == '') { + // Prompt for the db-url data if it was not provided via --db-url. + $database = $this->io()->ask('Database name', 'drupal'); + $driver = $this->io()->ask('Database driver', 'mysql'); + $username = $this->io()->ask('Database username', 'drupal'); + $password = $this->io()->ask('Database password', 'drupal'); + $host = $this->io()->ask('Database host', '127.0.0.1'); + $port = $this->io()->ask('Database port', '3306'); + $db_url = "$driver://$username:$password@$host:$port/$database"; + $commandData->input()->setOption('db-url', $db_url); + + try { + $sql = SqlBase::create($commandData->input()->getOptions()); + } catch (\Exception $e) { + throw new \Exception(dt('Could not determine database connection parameters. Pass --db-url option.')); + } + } + } + } + + /** + * Perform setup tasks before installation. + * + * @hook pre-command site-install + * + */ + public function pre(CommandData $commandData) + { + $sql = SqlBase::create($commandData->input()->getOptions()); + $db_spec = $sql->getDbSpec(); + + $aliasRecord = $this->siteAliasManager()->getSelf(); + $root = $aliasRecord->root(); + + $dir = $commandData->input()->getOption('sites-subdir'); + if (!$dir) { + // We will allow the 'uri' from the site alias to provide + // a fallback name when '--sites-subdir' is not specified, but + // only if the uri and the folder name match, and only if + // the sites directory has already been created. + $dir = $this->getSitesSubdirFromUri($root, $aliasRecord->get('uri')); + } + + if (!$dir) { + throw new \Exception(dt('Could not determine target sites directory for site to install. Use --sites-subdir to specify.')); + } + + $sites_subdir = Path::join('sites', $dir); + $confPath = $sites_subdir; + $settingsfile = Path::join($confPath, 'settings.php'); + $sitesfile = "sites/sites.php"; + $default = realpath(Path::join($root, 'sites/default')); + $sitesfile_write = realpath($confPath) != $default && !file_exists($sitesfile); + + if (!file_exists($settingsfile)) { + $msg[] = dt('create a @settingsfile file', ['@settingsfile' => $settingsfile]); + } + if ($sitesfile_write) { + $msg[] = dt('create a @sitesfile file', ['@sitesfile' => $sitesfile]); + } + if ($sql->dbExists()) { + $msg[] = dt("DROP all tables in your '@db' database.", ['@db' => $db_spec['database']]); + } else { + $msg[] = dt("CREATE the '@db' database.", ['@db' => $db_spec['database']]); + } + + if (!$this->io()->confirm(dt('You are about to ') . implode(dt(' and '), $msg) . ' Do you want to continue?')) { + throw new UserAbortException(); + } + + // Can't install without sites subdirectory and settings.php. + if (!file_exists($confPath)) { + if (!drush_mkdir($confPath) && !Drush::simulate()) { + throw new \Exception(dt('Failed to create directory @confPath', ['@confPath' => $confPath])); + } + } else { + $this->logger()->info(dt('Sites directory @subdir already exists - proceeding.', ['@subdir' => $confPath])); + } + + if (!drush_file_not_empty($settingsfile)) { + if (!drush_op('copy', 'sites/default/default.settings.php', $settingsfile) && !Drush::simulate()) { + throw new \Exception(dt('Failed to copy sites/default/default.settings.php to @settingsfile', ['@settingsfile' => $settingsfile])); + } + } + + // Write an empty sites.php if we using multi-site. + if ($sitesfile_write) { + if (!drush_op('copy', 'sites/example.sites.php', $sitesfile) && !Drush::simulate()) { + throw new \Exception(dt('Failed to copy sites/example.sites.php to @sitesfile', ['@sitesfile' => $sitesfile])); + } + } + + // We need to be at least at DRUSH_BOOTSTRAP_DRUPAL_SITE to select the site uri to install to + define('MAINTENANCE_MODE', 'install'); + $bootstrapManager = Drush::bootstrapManager(); + $bootstrapManager->doBootstrap(DRUSH_BOOTSTRAP_DRUPAL_SITE); + + if (!$sql->dropOrCreate()) { + throw new \Exception(dt('Failed to create database: @error', ['@error' => implode(drush_shell_exec_output())])); + } + } + + /** + * Determine an appropriate site subdir name to use for the + * provided uri. + */ + protected function getSitesSubdirFromUri($root, $uri) + { + $dir = strtolower($uri); + // Always accept simple uris (e.g. 'dev', 'stage', etc.) + if (preg_match('#^[a-z0-9_-]*$#', $dir)) { + return $dir; + } + // Strip off the protocol from the provided uri -- however, + // now we will require that the sites subdir already exist. + $dir = preg_replace('#[^/]*/*#', '', $dir); + if ($dir && file_exists(Path::join($root, $dir))) { + return $dir; + } + // Find the dir from sites.php file + $sites_file = $root . '/sites/sites.php'; + if (file_exists($sites_file)) { + include $sites_file; + if (array_key_exists($uri, $sites)) { + return $sites[$uri]; + } + } + return false; + } + + /** + * Fake the necessary HTTP headers that the Drupal installer still needs: + * @see https://github.com/drupal/drupal/blob/d260101f1ea8a6970df88d2f1899248985c499fc/core/includes/install.core.inc#L287 + */ + public function serverGlobals($drupal_base_url) + { + $drupal_base_url = parse_url($drupal_base_url); + + // Fill in defaults. + $drupal_base_url += [ + 'scheme' => null, + 'path' => '', + 'host' => null, + 'port' => null, + ]; + $_SERVER['HTTP_HOST'] = $drupal_base_url['host']; + + if ($drupal_base_url['scheme'] == 'https') { + $_SERVER['HTTPS'] = 'on'; + } + + if ($drupal_base_url['port']) { + $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port']; + } + $_SERVER['SERVER_PORT'] = $drupal_base_url['port']; + + $_SERVER['REQUEST_URI'] = $drupal_base_url['path'] . '/'; + + $_SERVER['PHP_SELF'] = $_SERVER['REQUEST_URI'] . 'index.php'; + $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF']; + $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; + $_SERVER['REQUEST_METHOD'] = 'GET'; + + $_SERVER['SERVER_SOFTWARE'] = null; + $_SERVER['HTTP_USER_AGENT'] = null; + $_SERVER['SCRIPT_FILENAME'] = DRUPAL_ROOT . '/index.php'; + } +}