Issue #1351352 by sun, lucascaro, Gábor Hojtsy, rupertj: Distribution installation profiles are no longer able to override the early installer screens.

8.0.x
Alex Pott 2014-03-14 10:49:27 +00:00
parent 9c66858942
commit e42ac27706
6 changed files with 184 additions and 65 deletions

View File

@ -205,6 +205,8 @@ function install_state_defaults() {
'profile_info' => array(),
// An array of available installation profiles.
'profiles' => array(),
// The name of the theme to use during installation.
'theme' => 'seven',
// The server URL where the interface translation files can be downloaded.
// Tokens in the pattern will be replaced by appropriate values for the
// required translation file.
@ -377,17 +379,6 @@ function install_begin_request(&$install_state) {
\Drupal::translation()->setDefaultLangcode($install_state['parameters']['langcode']);
}
$module_handler = \Drupal::moduleHandler();
if (!$module_handler->moduleExists('system')) {
// Override the module list with a minimal set of modules.
$module_handler->setModuleList(array('system' => 'core/modules/system/system.module'));
}
// After setting up a custom and finite module list in a custom low-level
// bootstrap like here, ensure to use ModuleHandler::loadAll() so that
// ModuleHandler::isLoaded() returns TRUE, since that is a condition being
// checked by other subsystems (e.g., the theme system).
$module_handler->loadAll();
// Add list of all available profiles to the installation state.
$listing = new ExtensionDiscovery();
$listing->setProfileDirectories(array());
@ -398,6 +389,30 @@ function install_begin_request(&$install_state) {
drupal_get_filename('profile', $name, $profile->uri);
}
if ($profile = _install_select_profile($install_state)) {
$install_state['parameters']['profile'] = $profile;
install_load_profile($install_state);
if (isset($install_state['profile_info']['distribution']['install']['theme'])) {
$install_state['theme'] = $install_state['profile_info']['distribution']['install']['theme'];
}
}
// Override the module list with a minimal set of modules.
$module_handler = \Drupal::moduleHandler();
$module_list = $module_handler->getModuleList();
if (!$module_handler->moduleExists('system')) {
$module_list['system'] = 'core/modules/system/system.module';
}
if ($profile && !$module_handler->moduleExists($profile)) {
$module_list[$profile] = $install_state['profiles'][$profile]->uri;
}
$module_handler->setModuleList($module_list);
// After setting up a custom and finite module list in a custom low-level
// bootstrap like here, ensure to use ModuleHandler::loadAll() so that
// ModuleHandler::isLoaded() returns TRUE, since that is a condition being
// checked by other subsystems (e.g., the theme system).
$module_handler->loadAll();
// Prepare for themed output. We need to run this at the beginning of the
// page request to avoid a different theme accidentally getting set. (We also
// need to run it even in the case of command-line installations, to prevent
@ -639,7 +654,7 @@ function install_tasks($install_state) {
),
'install_select_profile' => array(
'display_name' => t('Choose profile'),
'display' => count($install_state['profiles']) != 1,
'display' => empty($install_state['profile_info']['distribution']['name']) && count($install_state['profiles']) != 1,
'run' => INSTALL_TASK_RUN_IF_REACHED,
),
'install_load_profile' => array(
@ -664,7 +679,7 @@ function install_tasks($install_state) {
'run' => INSTALL_TASK_RUN_IF_REACHED,
),
'install_profile_modules' => array(
'display_name' => count($install_state['profiles']) == 1 ? t('Install site') : t('Installation profile'),
'display_name' => t('Install site'),
'type' => 'batch',
),
'install_import_translations' => array(
@ -1220,7 +1235,7 @@ function install_select_profile(&$install_state) {
throw new NoProfilesException(\Drupal::service('string_translation'));
}
// Try to automatically select a profile.
if ($profile = _install_select_profile($install_state['profiles'])) {
if ($profile = _install_select_profile($install_state)) {
$install_state['parameters']['profile'] = $profile;
}
else {
@ -1235,49 +1250,44 @@ function install_select_profile(&$install_state) {
}
/**
* Selects an installation profile.
* Determines the installation profile to use in the installer.
*
* A profile will be selected if:
* - Only one profile is available,
* - A profile was submitted through \Drupal::request()->request,
* - Exactly one of the profiles is marked as "exclusive".
* If multiple profiles are marked as "exclusive" then no profile will be
* selected.
* A profile will be selected in the following order of conditions:
*
* @param array $profiles
* An associative array of profiles with the machine-readable names as keys.
* 1. Only one profile is available.
* 2. A specific profile name is requested in installation parameters:
* - for interactive installations via request query parameters.
* - for non-interactive installations via install_drupal() settings.
* 3. A discovered profile that is a distribution.
* If multiple profiles are distributions, then the first discovered profile
* will be selected.
*
* @param array $install_state
* The current installer state, containing a 'profiles' key, which is an
* associative array of profiles with the machine-readable names as keys.
*
* @return
* The machine-readable name of the selected profile or NULL if no profile was
* selected.
*/
function _install_select_profile($profiles) {
function _install_select_profile(&$install_state) {
// Don't need to choose profile if only one available.
$request_params = \Drupal::request()->request;
if (count($profiles) == 1) {
$profile = array_pop($profiles);
return $profile->getName();
if (count($install_state['profiles']) == 1) {
return key($install_state['profiles']);
}
elseif ($request_params->has('profile') && ($profile = $request_params->get('profile')) && isset($profiles[$profile])) {
return $profiles[$profile]->getName();
}
// Check for a profile marked as "exclusive" and ensure that only one
// profile is marked as such.
$exclusive_profile = NULL;
foreach ($profiles as $profile) {
$profile_info = install_profile_info($profile->getName());
if (!empty($profile_info['exclusive'])) {
if (empty($exclusive_profile)) {
$exclusive_profile = $profile->getName();
}
else {
// We found a second "exclusive" profile. There's no way to choose
// between them, so we ignore the property.
return;
}
if (!empty($install_state['parameters']['profile'])) {
$profile = $install_state['parameters']['profile'];
if (isset($install_state['profiles'][$profile])) {
return $profile;
}
}
// Check for a distribution profile.
foreach ($install_state['profiles'] as $profile) {
$profile_info = install_profile_info($profile->getName());
if (!empty($profile_info['distribution'])) {
return $profile->getName();
}
}
return $exclusive_profile;
}
/**
@ -1351,6 +1361,14 @@ function install_select_profile_form($form, &$form_state, $install_state) {
return $form;
}
/**
* Form submission handler for install_select_profile_form().
*/
function install_select_profile_form_submit($form, &$form_state) {
global $install_state;
$install_state['parameters']['profile'] = $form_state['values']['profile'];
}
/**
* Finds all .po files that are useful to the installer.
*
@ -1755,7 +1773,7 @@ function install_load_profile(&$install_state) {
$profile_file = $install_state['profiles'][$profile]->uri;
if (file_exists($profile_file)) {
include_once DRUPAL_ROOT . '/' . $profile_file;
$install_state['profile_info'] = install_profile_info($install_state['parameters']['profile'], $install_state['parameters']['langcode']);
$install_state['profile_info'] = install_profile_info($install_state['parameters']['profile'], isset($install_state['parameters']['langcode']) ? $install_state['parameters']['langcode'] : 'en');
}
else {
throw new InstallerException(t('Sorry, the profile you have chosen cannot be loaded.'));

View File

@ -95,16 +95,19 @@ function drupal_load_updates() {
function drupal_install_profile_distribution_name() {
// During installation, the profile information is stored in the global
// installation state (it might not be saved anywhere yet).
$info = array();
if (drupal_installation_attempted()) {
global $install_state;
return isset($install_state['profile_info']['distribution_name']) ? $install_state['profile_info']['distribution_name'] : 'Drupal';
if (isset($install_state['profile_info'])) {
$info = $install_state['profile_info'];
}
}
// At all other times, we load the profile via standard methods.
else {
$profile = drupal_get_profile();
$info = system_get_info('module', $profile);
return $info['distribution_name'];
}
return isset($info['distribution']['name']) ? $info['distribution']['name'] : 'Drupal';
}
/**
@ -1046,15 +1049,19 @@ function drupal_check_module($module) {
* Additional, less commonly-used information that can appear in a
* profile.info.yml file but not in a normal Drupal module .info.yml file
* includes:
* - distribution_name: The name of the Drupal distribution that is being
* installed, to be shown throughout the installation process. Defaults to
* 'Drupal'.
* - exclusive: If the install profile is intended to be the only eligible
* choice in a distribution, setting exclusive = TRUE will auto-select it
* during installation, and the install profile selection screen will be
* skipped. If more than one profile is found where exclusive = TRUE then
* this property will have no effect and the profile selection screen will
* be shown as normal with all available profiles shown.
*
* - distribution: Existence of this key denotes that the installation profile
* is intended to be the only eligible choice in a distribution and will be
* auto-selected during installation, whereas the installation profile
* selection screen will be skipped. If more than one distribution profile is
* found then the first one discovered will be selected.
* The following subproperties may be set:
* - name: The name of the distribution that is being installed, to be shown
* throughout the installation process. If omitted,
* drupal_install_profile_distribution_name() defaults to 'Drupal'.
* - install: Optional parameters to override the installer:
* - theme: The machine name of a theme to use in the installer instead of
* Drupal's default installer theme.
*
* Note that this function does an expensive file system scan to get info file
* information for dependencies. If you only need information from the info
@ -1084,7 +1091,6 @@ function install_profile_info($profile, $langcode = 'en') {
$defaults = array(
'dependencies' => array(),
'description' => '',
'distribution_name' => 'Drupal',
'version' => NULL,
'hidden' => FALSE,
'php' => DRUPAL_MINIMUM_PHP,

View File

@ -2360,7 +2360,11 @@ function template_preprocess_install_page(&$variables) {
$variables['attributes']['class'][] = 'install-page';
// Override the site name that is displayed on the page, since Drupal is
// still in the process of being installed.
$variables['site_name'] = drupal_install_profile_distribution_name();
$distribution_name = String::checkPlain(drupal_install_profile_distribution_name());
$variables['site_name'] = $distribution_name;
$variables['head_title_array']['name'] = $distribution_name;
$variables['head_title'] = implode(' | ', $variables['head_title_array']);
}
/**

View File

@ -34,7 +34,12 @@ function _drupal_maintenance_theme() {
// Install and update pages are treated differently to prevent theming overrides.
if (defined('MAINTENANCE_MODE') && (MAINTENANCE_MODE == 'install' || MAINTENANCE_MODE == 'update')) {
$custom_theme = settings()->get('maintenance_theme', 'seven');
if (drupal_installation_attempted()) {
$custom_theme = $GLOBALS['install_state']['theme'];
}
else {
$custom_theme = settings()->get('maintenance_theme', 'seven');
}
}
else {
// The bootstrap was not complete. So we are operating in a crippled

View File

@ -0,0 +1,85 @@
<?php
/**
* @file
* Contains \Drupal\system\Tests\Installer\DistributionProfileTest.
*/
namespace Drupal\system\Tests\Installer;
use Drupal\simpletest\InstallerTestBase;
use Symfony\Component\Yaml\Yaml;
/**
* Tests the installer translation detection.
*/
class DistributionProfileTest extends InstallerTestBase {
/**
* The distribution profile info.
*
* @var array
*/
protected $info;
public static function getInfo() {
return array(
'name' => 'Distribution installation profile test',
'description' => 'Tests distribution profile support.',
'group' => 'Installer',
);
}
protected function setUp() {
$this->info = array(
'type' => 'profile',
'core' => \Drupal::CORE_COMPATIBILITY,
'name' => 'Distribution profile',
'distribution' => array(
'name' => 'My Distribution',
'install' => array(
'theme' => 'bartik',
),
),
);
// File API functions are not available yet.
$path = $this->siteDirectory . '/profiles/mydistro';
mkdir($path, 0777, TRUE);
file_put_contents("$path/mydistro.info.yml", Yaml::dump($this->info, PHP_INT_MAX, 2));
file_put_contents("$path/mydistro.profile", "<?php\n");
parent::setUp();
}
/**
* Overrides InstallerTest::setUpLanguage().
*/
protected function setUpLanguage() {
// Verify that the distribution name appears.
$this->assertRaw($this->info['distribution']['name']);
// Verify that the requested theme is used.
$this->assertRaw($this->info['distribution']['install']['theme']);
// Verify that the "Choose profile" step does not appear.
$this->assertNoText('profile');
parent::setUpLanguage();
}
/**
* Overrides InstallerTest::setUpProfile().
*/
protected function setUpProfile() {
// This step is skipped, because there is a distribution profile.
}
/**
* Confirms that the installation succeeded.
*/
public function testInstalled() {
$this->assertUrl('user/1');
$this->assertResponse(200);
// Confirm that we are logged-in after installation.
$this->assertText($this->root_user->getUsername());
}
}

View File

@ -1425,10 +1425,11 @@ function _system_rebuild_module_data() {
if ($profile && isset($modules[$profile])) {
// The installation profile is required, if it's a valid module.
$modules[$profile]->info['required'] = TRUE;
// Add a default distribution name if the profile did not provide one. This
// matches the default value used in install_profile_info().
if (!isset($modules[$profile]->info['distribution_name'])) {
$modules[$profile]->info['distribution_name'] = 'Drupal';
// Add a default distribution name if the profile did not provide one.
// @see install_profile_info()
// @see drupal_install_profile_distribution_name()
if (!isset($modules[$profile]->info['distribution']['name'])) {
$modules[$profile]->info['distribution']['name'] = 'Drupal';
}
}