Issue #2156401 by alexpott, moshe weitzman, tedbow, dawehner, greg.1.anderson, phenaproxima, chris.smith, heddn, balsama, xjm, Mile23, izus, Manuel Garcia, sun, pwolanin, Berdir: Write install_profile value to configuration and only to settings.php if it is writeable
parent
43f6069295
commit
ebe2d76141
|
@ -1,2 +1,3 @@
|
|||
module: {}
|
||||
theme: {}
|
||||
profile: ''
|
||||
|
|
|
@ -14,3 +14,6 @@ core.extension:
|
|||
sequence:
|
||||
type: integer
|
||||
label: 'Weight'
|
||||
profile:
|
||||
type: string
|
||||
label: 'Install profile'
|
||||
|
|
|
@ -303,7 +303,7 @@ services:
|
|||
- { name: event_subscriber }
|
||||
config.installer:
|
||||
class: Drupal\Core\Config\ConfigInstaller
|
||||
arguments: ['@config.factory', '@config.storage', '@config.typed', '@config.manager', '@event_dispatcher']
|
||||
arguments: ['@config.factory', '@config.storage', '@config.typed', '@config.manager', '@event_dispatcher', '%install_profile%']
|
||||
lazy: true
|
||||
config.storage:
|
||||
class: Drupal\Core\Config\CachedStorage
|
||||
|
@ -328,7 +328,7 @@ services:
|
|||
- { name: backend_overridable }
|
||||
config.storage.schema:
|
||||
class: Drupal\Core\Config\ExtensionInstallStorage
|
||||
arguments: ['@config.storage', 'config/schema']
|
||||
arguments: ['@config.storage', 'config/schema', '', true, '%install_profile%']
|
||||
config.typed:
|
||||
class: Drupal\Core\Config\TypedConfigManager
|
||||
arguments: ['@config.storage', '@config.storage.schema', '@cache.discovery', '@module_handler']
|
||||
|
|
|
@ -9,6 +9,7 @@ use Drupal\Component\Utility\Crypt;
|
|||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Config\BootstrapConfigStorageFactory;
|
||||
use Drupal\Core\Logger\RfcLogLevel;
|
||||
use Drupal\Core\Render\Markup;
|
||||
use Drupal\Component\Render\MarkupInterface;
|
||||
|
@ -727,12 +728,20 @@ function drupal_installation_attempted() {
|
|||
* When this function is called during Drupal's initial installation process,
|
||||
* the name of the profile that's about to be installed is stored in the global
|
||||
* installation state. At all other times, the "install_profile" setting will be
|
||||
* available in settings.php.
|
||||
* available in container as a parameter.
|
||||
*
|
||||
* @return string|null $profile
|
||||
* The name of the installation profile or NULL if no installation profile is
|
||||
* currently active. This is the case for example during the first steps of
|
||||
* the installer or during unit tests.
|
||||
*
|
||||
* @deprecated in Drupal 8.3.0, will be removed before Drupal 9.0.0.
|
||||
* Use the install_profile container parameter or \Drupal::installProfile()
|
||||
* instead. If you are accessing the value before it is written to
|
||||
* configuration during the installer use the $install_state global. If you
|
||||
* need to access the value before container is available you can use
|
||||
* BootstrapConfigStorageFactory to load the value directly from
|
||||
* configuration.
|
||||
*/
|
||||
function drupal_get_profile() {
|
||||
global $install_state;
|
||||
|
@ -747,8 +756,18 @@ function drupal_get_profile() {
|
|||
}
|
||||
}
|
||||
else {
|
||||
// Fall back to NULL, if there is no 'install_profile' setting.
|
||||
$profile = Settings::get('install_profile');
|
||||
if (\Drupal::hasContainer()) {
|
||||
$profile = \Drupal::installProfile();
|
||||
}
|
||||
else {
|
||||
$profile = BootstrapConfigStorageFactory::getDatabaseStorage()->read('core.extension')['profile'];
|
||||
}
|
||||
|
||||
// A BC layer just in in case this only exists in Settings. Introduced in
|
||||
// Drupal 8.3.x and will be removed before Drupal 9.0.0.
|
||||
if (empty($profile)) {
|
||||
$profile = Settings::get('install_profile');
|
||||
}
|
||||
}
|
||||
|
||||
return $profile;
|
||||
|
|
|
@ -12,6 +12,7 @@ use Drupal\Core\Database\DatabaseExceptionWrapper;
|
|||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Installer\Exception\AlreadyInstalledException;
|
||||
use Drupal\Core\Installer\Exception\InstallerException;
|
||||
use Drupal\Core\Installer\Exception\InstallProfileMismatchException;
|
||||
use Drupal\Core\Installer\Exception\NoProfilesException;
|
||||
use Drupal\Core\Installer\InstallerKernel;
|
||||
use Drupal\Core\Language\Language;
|
||||
|
@ -2188,13 +2189,23 @@ function install_display_requirements($install_state, $requirements) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Installation task; ensures install profile is written to settings.php.
|
||||
* Installation task; writes profile to settings.php if possible.
|
||||
*
|
||||
* @param array $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @see _install_select_profile()
|
||||
*
|
||||
* @throws \Drupal\Core\Installer\Exception\InstallProfileMismatchException
|
||||
*
|
||||
* @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. The
|
||||
* install profile is written to core.extension.
|
||||
*/
|
||||
function install_write_profile($install_state) {
|
||||
if (Settings::get('install_profile') !== $install_state['parameters']['profile']) {
|
||||
// Only need to write to settings.php if it is possible. The primary storage
|
||||
// for the install profile is the core.extension configuration.
|
||||
$settings_path = \Drupal::service('site.path') . '/settings.php';
|
||||
if (is_writable($settings_path)) {
|
||||
// Remember the profile which was used.
|
||||
$settings['settings']['install_profile'] = (object) array(
|
||||
'value' => $install_state['parameters']['profile'],
|
||||
|
@ -2202,4 +2213,7 @@ function install_write_profile($install_state) {
|
|||
);
|
||||
drupal_rewrite_settings($settings);
|
||||
}
|
||||
elseif (($settings_profile = Settings::get('install_profile')) && $settings_profile !== $install_state['parameters']['profile']) {
|
||||
throw new InstallProfileMismatchException($install_state['parameters']['profile'], $settings_profile, $settings_path, \Drupal::translation());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -621,6 +621,12 @@ function drupal_install_system($install_state) {
|
|||
// Install base system configuration.
|
||||
\Drupal::service('config.installer')->installDefaultConfig('core', 'core');
|
||||
|
||||
// Store the installation profile in configuration to populate the
|
||||
// 'install_profile' container parameter.
|
||||
\Drupal::configFactory()->getEditable('core.extension')
|
||||
->set('profile', $install_state['parameters']['profile'])
|
||||
->save();
|
||||
|
||||
// Install System module and rebuild the newly available routes.
|
||||
$kernel->getContainer()->get('module_installer')->install(array('system'), FALSE);
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
|
|
@ -181,6 +181,16 @@ class Drupal {
|
|||
return static::getContainer()->get('app.root');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the active install profile.
|
||||
*
|
||||
* @return string|null
|
||||
* The name of the active install profile.
|
||||
*/
|
||||
public static function installProfile() {
|
||||
return static::getContainer()->getParameter('install_profile');
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if there is a currently active request object.
|
||||
*
|
||||
|
|
|
@ -6,7 +6,6 @@ use Drupal\Component\Utility\Crypt;
|
|||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Config\Entity\ConfigDependencyManager;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityDependency;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
class ConfigInstaller implements ConfigInstallerInterface {
|
||||
|
@ -60,6 +59,13 @@ class ConfigInstaller implements ConfigInstallerInterface {
|
|||
*/
|
||||
protected $isSyncing = FALSE;
|
||||
|
||||
/**
|
||||
* The name of the currently active installation profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $installProfile;
|
||||
|
||||
/**
|
||||
* Constructs the configuration installer.
|
||||
*
|
||||
|
@ -73,13 +79,16 @@ class ConfigInstaller implements ConfigInstallerInterface {
|
|||
* The configuration manager.
|
||||
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
|
||||
* The event dispatcher.
|
||||
* @param string $install_profile
|
||||
* The name of the currently active installation profile.
|
||||
*/
|
||||
public function __construct(ConfigFactoryInterface $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, ConfigManagerInterface $config_manager, EventDispatcherInterface $event_dispatcher) {
|
||||
public function __construct(ConfigFactoryInterface $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, ConfigManagerInterface $config_manager, EventDispatcherInterface $event_dispatcher, $install_profile) {
|
||||
$this->configFactory = $config_factory;
|
||||
$this->activeStorages[$active_storage->getCollectionName()] = $active_storage;
|
||||
$this->typedConfig = $typed_config;
|
||||
$this->configManager = $config_manager;
|
||||
$this->eventDispatcher = $event_dispatcher;
|
||||
$this->installProfile = $install_profile;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -140,7 +149,7 @@ class ConfigInstaller implements ConfigInstallerInterface {
|
|||
// Install any optional configuration entities whose dependencies can now
|
||||
// be met. This searches all the installed modules config/optional
|
||||
// directories.
|
||||
$storage = new ExtensionInstallStorage($this->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, FALSE);
|
||||
$storage = new ExtensionInstallStorage($this->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, FALSE, $this->installProfile);
|
||||
$this->installOptionalConfig($storage, [$type => $name]);
|
||||
}
|
||||
|
||||
|
@ -156,11 +165,11 @@ class ConfigInstaller implements ConfigInstallerInterface {
|
|||
$optional_profile_config = [];
|
||||
if (!$storage) {
|
||||
// Search the install profile's optional configuration too.
|
||||
$storage = new ExtensionInstallStorage($this->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, TRUE);
|
||||
$storage = new ExtensionInstallStorage($this->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_OPTIONAL_DIRECTORY, StorageInterface::DEFAULT_COLLECTION, TRUE, $this->installProfile);
|
||||
// The extension install storage ensures that overrides are used.
|
||||
$profile_storage = NULL;
|
||||
}
|
||||
elseif (isset($profile)) {
|
||||
elseif (!empty($profile)) {
|
||||
// Creates a profile storage to search for overrides.
|
||||
$profile_install_path = $this->drupalGetPath('module', $profile) . '/' . InstallStorage::CONFIG_OPTIONAL_DIRECTORY;
|
||||
$profile_storage = new FileStorage($profile_install_path, StorageInterface::DEFAULT_COLLECTION);
|
||||
|
@ -331,7 +340,7 @@ class ConfigInstaller implements ConfigInstallerInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function installCollectionDefaultConfig($collection) {
|
||||
$storage = new ExtensionInstallStorage($this->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_INSTALL_DIRECTORY, $collection, $this->drupalInstallationAttempted());
|
||||
$storage = new ExtensionInstallStorage($this->getActiveStorages(StorageInterface::DEFAULT_COLLECTION), InstallStorage::CONFIG_INSTALL_DIRECTORY, $collection, $this->drupalInstallationAttempted(), $this->installProfile);
|
||||
// Only install configuration for enabled extensions.
|
||||
$enabled_extensions = $this->getEnabledExtensions();
|
||||
$config_to_install = array_filter($storage->listAll(), function ($config_name) use ($enabled_extensions) {
|
||||
|
@ -672,9 +681,7 @@ class ConfigInstaller implements ConfigInstallerInterface {
|
|||
* of the installer or during unit tests.
|
||||
*/
|
||||
protected function drupalGetProfile() {
|
||||
// Settings is safe to use because settings.php is written before any module
|
||||
// is installed.
|
||||
return Settings::get('install_profile');
|
||||
return $this->installProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Core\Config;
|
||||
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\Extension\ExtensionDiscovery;
|
||||
|
||||
/**
|
||||
|
@ -27,6 +26,13 @@ class ExtensionInstallStorage extends InstallStorage {
|
|||
*/
|
||||
protected $includeProfile = TRUE;
|
||||
|
||||
/**
|
||||
* The name of the currently active installation profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $installProfile;
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Core\Config\InstallStorage::__construct().
|
||||
*
|
||||
|
@ -42,11 +48,19 @@ class ExtensionInstallStorage extends InstallStorage {
|
|||
* @param bool $include_profile
|
||||
* (optional) Whether to include the install profile in extensions to
|
||||
* search and to get overrides from.
|
||||
* @param string $profile
|
||||
* (optional) The current installation profile. This parameter will be
|
||||
* mandatory in Drupal 9.0.0. In Drupal 8.3.0 not providing this parameter
|
||||
* will trigger a silenced deprecation warning.
|
||||
*/
|
||||
public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, $include_profile = TRUE) {
|
||||
public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, $include_profile = TRUE, $profile = NULL) {
|
||||
parent::__construct($directory, $collection);
|
||||
$this->configStorage = $config_storage;
|
||||
$this->includeProfile = $include_profile;
|
||||
if (is_null($profile)) {
|
||||
@trigger_error('Install profile will be a mandatory parameter in Drupal 9.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
$this->installProfile = $profile ?: \Drupal::installProfile();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,22 +91,20 @@ class ExtensionInstallStorage extends InstallStorage {
|
|||
$this->folders = array();
|
||||
$this->folders += $this->getCoreNames();
|
||||
|
||||
$install_profile = Settings::get('install_profile');
|
||||
$profile = drupal_get_profile();
|
||||
$extensions = $this->configStorage->read('core.extension');
|
||||
// @todo Remove this scan as part of https://www.drupal.org/node/2186491
|
||||
$listing = new ExtensionDiscovery(\Drupal::root());
|
||||
if (!empty($extensions['module'])) {
|
||||
$modules = $extensions['module'];
|
||||
// Remove the install profile as this is handled later.
|
||||
unset($modules[$install_profile]);
|
||||
unset($modules[$this->installProfile]);
|
||||
$profile_list = $listing->scan('profile');
|
||||
if ($profile && isset($profile_list[$profile])) {
|
||||
if ($this->installProfile && isset($profile_list[$this->installProfile])) {
|
||||
// Prime the drupal_get_filename() static cache with the profile info
|
||||
// file location so we can use drupal_get_path() on the active profile
|
||||
// during the module scan.
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491
|
||||
drupal_get_filename('profile', $profile, $profile_list[$profile]->getPathname());
|
||||
drupal_get_filename('profile', $this->installProfile, $profile_list[$this->installProfile]->getPathname());
|
||||
}
|
||||
$module_list_scan = $listing->scan('module');
|
||||
$module_list = array();
|
||||
|
@ -117,12 +129,12 @@ class ExtensionInstallStorage extends InstallStorage {
|
|||
// The install profile can override module default configuration. We do
|
||||
// this by replacing the config file path from the module/theme with the
|
||||
// install profile version if there are any duplicates.
|
||||
if (isset($profile)) {
|
||||
if ($this->installProfile) {
|
||||
if (!isset($profile_list)) {
|
||||
$profile_list = $listing->scan('profile');
|
||||
}
|
||||
if (isset($profile_list[$profile])) {
|
||||
$profile_folders = $this->getComponentNames(array($profile_list[$profile]));
|
||||
if (isset($profile_list[$this->installProfile])) {
|
||||
$profile_folders = $this->getComponentNames(array($profile_list[$this->installProfile]));
|
||||
$this->folders = $profile_folders + $this->folders;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1204,6 +1204,7 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
|
|||
$container = $this->getContainerBuilder();
|
||||
$container->set('kernel', $this);
|
||||
$container->setParameter('container.modules', $this->getModulesParameter());
|
||||
$container->setParameter('install_profile', $this->getInstallProfile());
|
||||
|
||||
// Get a list of namespaces and put it onto the container.
|
||||
$namespaces = $this->getModuleNamespacesPsr4($this->getModuleFileNames());
|
||||
|
@ -1561,4 +1562,25 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
|
|||
$this->serviceYamls['site'] = array_filter($service_yamls, 'file_exists');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the active install profile.
|
||||
*
|
||||
* @return string|null
|
||||
* The name of the any active install profile or distribution.
|
||||
*/
|
||||
protected function getInstallProfile() {
|
||||
$config = $this->getConfigStorage()->read('core.extension');
|
||||
if (!empty($config['profile'])) {
|
||||
$install_profile = $config['profile'];
|
||||
}
|
||||
// @todo https://www.drupal.org/node/2831065 remove the BC layer.
|
||||
else {
|
||||
// If system_update_8300() has not yet run fallback to using settings.
|
||||
$install_profile = Settings::get('install_profile');
|
||||
}
|
||||
|
||||
// Normalize an empty string to a NULL value.
|
||||
return empty($install_profile) ? NULL : $install_profile;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use Drupal\Core\Config\ConfigImporterEvent;
|
|||
use Drupal\Core\Config\ConfigImportValidateEventSubscriberBase;
|
||||
use Drupal\Core\Config\ConfigNameException;
|
||||
use Drupal\Core\Extension\ThemeHandlerInterface;
|
||||
use Drupal\Core\Site\Settings;
|
||||
|
||||
/**
|
||||
* Config import subscriber for config import events.
|
||||
|
@ -112,9 +111,10 @@ class ConfigImportSubscriber extends ConfigImportValidateEventSubscriberBase {
|
|||
}
|
||||
}
|
||||
|
||||
// Settings is safe to use because settings.php is written before any module
|
||||
// is installed.
|
||||
$install_profile = Settings::get('install_profile');
|
||||
// Get the install profile from the site's configuration.
|
||||
$current_core_extension = $config_importer->getStorageComparer()->getTargetStorage()->read('core.extension');
|
||||
$install_profile = isset($current_core_extension['profile']) ? $current_core_extension['profile'] : NULL;
|
||||
|
||||
// Ensure that all modules being uninstalled are not required by modules
|
||||
// that will be installed after the import.
|
||||
$uninstalls = $config_importer->getExtensionChangelist('module', 'uninstall');
|
||||
|
@ -129,10 +129,15 @@ class ConfigImportSubscriber extends ConfigImportValidateEventSubscriberBase {
|
|||
}
|
||||
|
||||
// Ensure that the install profile is not being uninstalled.
|
||||
if (in_array($install_profile, $uninstalls)) {
|
||||
if (in_array($install_profile, $uninstalls, TRUE)) {
|
||||
$profile_name = $module_data[$install_profile]->info['name'];
|
||||
$config_importer->logError($this->t('Unable to uninstall the %profile profile since it is the install profile.', array('%profile' => $profile_name)));
|
||||
}
|
||||
|
||||
// Ensure the profile is not changing.
|
||||
if ($install_profile !== $core_extension['profile']) {
|
||||
$config_importer->logError($this->t('Cannot change the install profile from %new_profile to %profile once Drupal is installed.', array('%profile' => $install_profile, '%new_profile' => $core_extension['profile'])));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Installer\Exception;
|
||||
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
|
||||
/**
|
||||
* Exception thrown if settings.php cannot be written and the chosen profile does not match.
|
||||
*/
|
||||
class InstallProfileMismatchException extends InstallerException {
|
||||
|
||||
/**
|
||||
* Constructs a new InstallProfileMismatchException exception.
|
||||
*
|
||||
* @param string $selected_profile
|
||||
* The profile selected by _install_select_profile().
|
||||
* @param string $settings_profile
|
||||
* The profile in settings.php.
|
||||
* @param string $settings_file
|
||||
* The path to settigns.php.
|
||||
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
|
||||
* The string translation manager.
|
||||
*
|
||||
* @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. The
|
||||
* install profile is written to core.extension.
|
||||
*
|
||||
* @see _install_select_profile()
|
||||
* @see install_write_profile
|
||||
*/
|
||||
public function __construct($selected_profile, $settings_profile, $settings_file, TranslationInterface $string_translation) {
|
||||
$this->stringTranslation = $string_translation;
|
||||
|
||||
$title = $this->t('Install profile mismatch');
|
||||
$message = $this->t(
|
||||
'The selected profile %profile does not match the install_profile setting, which is %settings_profile. Cannot write updated setting to %settings_file.',
|
||||
[
|
||||
'%profile' => $selected_profile,
|
||||
'%settings_profile' => $settings_profile,
|
||||
'%settings_file' => $settings_file,
|
||||
]
|
||||
);
|
||||
parent::__construct($message, $title);
|
||||
}
|
||||
|
||||
}
|
|
@ -46,4 +46,24 @@ class InstallerKernel extends DrupalKernel {
|
|||
return parent::getConfigStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInstallProfile() {
|
||||
global $install_state;
|
||||
if ($install_state && empty($install_state['installation_finished'])) {
|
||||
// If the profile has been selected return it.
|
||||
if (isset($install_state['parameters']['profile'])) {
|
||||
$profile = $install_state['parameters']['profile'];
|
||||
}
|
||||
else {
|
||||
$profile = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$profile = parent::getInstallProfile();
|
||||
}
|
||||
return $profile;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
services:
|
||||
locale.default.config.storage:
|
||||
class: Drupal\locale\LocaleDefaultConfigStorage
|
||||
arguments: ['@config.storage', '@language_manager']
|
||||
arguments: ['@config.storage', '@language_manager', '%install_profile%']
|
||||
public: false
|
||||
locale.config_manager:
|
||||
class: Drupal\locale\LocaleConfigManager
|
||||
|
|
|
@ -57,12 +57,12 @@ class LocaleDefaultConfigStorage {
|
|||
* @param \Drupal\language\ConfigurableLanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
public function __construct(StorageInterface $config_storage, ConfigurableLanguageManagerInterface $language_manager) {
|
||||
public function __construct(StorageInterface $config_storage, ConfigurableLanguageManagerInterface $language_manager, $install_profile) {
|
||||
$this->configStorage = $config_storage;
|
||||
$this->languageManager = $language_manager;
|
||||
|
||||
$this->requiredInstallStorage = new ExtensionInstallStorage($this->configStorage);
|
||||
$this->optionalInstallStorage = new ExtensionInstallStorage($this->configStorage, ExtensionInstallStorage::CONFIG_OPTIONAL_DIRECTORY);
|
||||
$this->requiredInstallStorage = new ExtensionInstallStorage($this->configStorage, ExtensionInstallStorage::CONFIG_INSTALL_DIRECTORY, ExtensionInstallStorage::DEFAULT_COLLECTION, TRUE, $install_profile);
|
||||
$this->optionalInstallStorage = new ExtensionInstallStorage($this->configStorage, ExtensionInstallStorage::CONFIG_OPTIONAL_DIRECTORY, ExtensionInstallStorage::DEFAULT_COLLECTION, TRUE, $install_profile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -232,7 +232,7 @@ EOD;
|
|||
// \Drupal\Core\Config\ConfigInstaller::installDefaultConfig() to work.
|
||||
// Write directly to active storage to avoid early instantiation of
|
||||
// the event dispatcher which can prevent modules from registering events.
|
||||
\Drupal::service('config.storage')->write('core.extension', array('module' => array(), 'theme' => array()));
|
||||
\Drupal::service('config.storage')->write('core.extension', array('module' => array(), 'theme' => array(), 'profile' => ''));
|
||||
|
||||
// Collect and set a fixed module list.
|
||||
$class = get_class($this);
|
||||
|
|
|
@ -323,13 +323,13 @@ EOS;
|
|||
}
|
||||
|
||||
/**
|
||||
* Tests that drupal_get_profile() returns NULL.
|
||||
* Tests that \Drupal::installProfile() returns NULL.
|
||||
*
|
||||
* As the currently active installation profile is used when installing
|
||||
* configuration, for example, this is essential to ensure test isolation.
|
||||
*/
|
||||
public function testDrupalGetProfile() {
|
||||
$this->assertNull(drupal_get_profile());
|
||||
$this->assertNull(\Drupal::installProfile());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
|
||||
/**
|
||||
* Tests distribution profile support with existing settings.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class DistributionProfileExistingSettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Distribution profile',
|
||||
'distribution' => [
|
||||
'name' => 'My Distribution',
|
||||
'install' => [
|
||||
'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::encode($this->info));
|
||||
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) [
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Use the kernel to find the site path because the site.path service should
|
||||
// not be available at this point in the install process.
|
||||
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
|
||||
// Pre-configure config directories.
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => $site_path . '/files/config_staging',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Make settings file not writable.
|
||||
$filename = $this->siteDirectory . '/settings.php';
|
||||
// Make the settings file read-only.
|
||||
// Not using File API; a potential error must trigger a PHP warning.
|
||||
chmod($filename, 0444);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->rootUser->getUsername());
|
||||
|
||||
// Confirm that Drupal recognizes this distribution as the current profile.
|
||||
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
|
||||
$this->assertNull(Settings::get('install_profile'), 'The install profile has not been written to settings.php.');
|
||||
$this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.');
|
||||
|
||||
$this->rebuildContainer();
|
||||
$this->pass('Container can be rebuilt even though distribution is not written to settings.php.');
|
||||
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
|
@ -68,6 +69,11 @@ class DistributionProfileTest extends InstallerTestBase {
|
|||
$this->assertResponse(200);
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getUsername());
|
||||
|
||||
// Confirm that Drupal recognizes this distribution as the current profile.
|
||||
$this->assertEqual(\Drupal::installProfile(), 'mydistro');
|
||||
$this->assertEqual(Settings::get('install_profile'), 'mydistro', 'The install profile has been written to settings.php.');
|
||||
$this->assertEqual($this->config('core.extension')->get('profile'), 'mydistro', 'The install profile has been written to core.extension configuration.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests installer breaks with a profile mismatch and a read-only settings.php.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingSettingsMismatchProfileBrokenTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Configures a preexisting settings.php file without an install_profile
|
||||
* setting before invoking the interactive installer.
|
||||
*/
|
||||
protected function setUp() {
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) [
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) [
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// During interactive install we'll change this to a different profile and
|
||||
// this test will ensure that the new value is written to settings.php.
|
||||
$this->settings['settings']['install_profile'] = (object) [
|
||||
'value' => 'minimal',
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure config directories.
|
||||
$site_path = DrupalKernel::findSitePath(Request::createFromGlobals());
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'value' => $site_path . '/files/config_staging',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Make settings file not writable. This will break the installer.
|
||||
$filename = $this->siteDirectory . '/settings.php';
|
||||
// Make the settings file read-only.
|
||||
// Not using File API; a potential error must trigger a PHP warning.
|
||||
chmod($filename, 0444);
|
||||
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php?langcode=en&profile=testing');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because there is a lagcode as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a profile as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
protected function setUpSite() {
|
||||
// This step should not appear, since settings.php could not be written.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation did not succeed.
|
||||
*/
|
||||
public function testBrokenInstaller() {
|
||||
$this->assertTitle('Install profile mismatch | Drupal');
|
||||
$this->assertText("The selected profile testing does not match the install_profile setting, which is minimal. Cannot write updated setting to {$this->siteDirectory}/settings.php.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing settings file but no install profile.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingSettingsMismatchProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Configures a preexisting settings.php file without an install_profile
|
||||
* setting before invoking the interactive installer.
|
||||
*/
|
||||
protected function setUp() {
|
||||
// Pre-configure hash salt.
|
||||
// Any string is valid, so simply use the class name of this test.
|
||||
$this->settings['settings']['hash_salt'] = (object) array(
|
||||
'value' => __CLASS__,
|
||||
'required' => TRUE,
|
||||
);
|
||||
|
||||
// Pre-configure database credentials.
|
||||
$connection_info = Database::getConnectionInfo();
|
||||
unset($connection_info['default']['pdo']);
|
||||
unset($connection_info['default']['init_commands']);
|
||||
|
||||
$this->settings['databases']['default'] = (object) array(
|
||||
'value' => $connection_info,
|
||||
'required' => TRUE,
|
||||
);
|
||||
|
||||
// During interactive install we'll change this to a different profile and
|
||||
// this test will ensure that the new value is written to settings.php.
|
||||
$this->settings['settings']['install_profile'] = (object) [
|
||||
'value' => 'minimal',
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
// Pre-configure config directories.
|
||||
$this->settings['config_directories'] = array(
|
||||
CONFIG_SYNC_DIRECTORY => (object) array(
|
||||
'value' => DrupalKernel::findSitePath(Request::createFromGlobals()) . '/files/config_sync',
|
||||
'required' => TRUE,
|
||||
),
|
||||
);
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Provide profile and language in query string to skip these pages.
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php?langcode=en&profile=testing');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because there is a lagcode as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a profile as a query param.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear, since settings.php is fully configured
|
||||
// already.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual('testing', \Drupal::installProfile());
|
||||
$this->assertEqual('testing', Settings::get('install_profile'), 'Profile was correctly changed to testing in Settings.php');
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
@ -65,7 +64,7 @@ class InstallerExistingSettingsNoProfileTest extends InstallerTestBase {
|
|||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual('testing', Settings::get('install_profile'));
|
||||
$this->assertEqual('testing', \Drupal::installProfile());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DrupalKernel;
|
||||
|
@ -74,7 +75,8 @@ class InstallerExistingSettingsTest extends InstallerTestBase {
|
|||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual('testing', drupal_get_profile(), 'Profile was changed from minimal to testing during interactive install.');
|
||||
$this->assertEqual('testing', \Drupal::installProfile(), 'Profile was changed from minimal to testing during interactive install.');
|
||||
$this->assertEqual('testing', Settings::get('install_profile'), 'Profile was correctly changed to testing in Settings.php');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Component\Serialization\Yaml;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests multiple distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class MultipleDistributionsProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
// Create two distributions.
|
||||
foreach (['distribution_one', 'distribution_two'] as $name) {
|
||||
$info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => $name . ' profile',
|
||||
'distribution' => [
|
||||
'name' => $name,
|
||||
'install' => [
|
||||
'theme' => 'bartik',
|
||||
],
|
||||
],
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->siteDirectory . '/profiles/' . $name;
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/$name.info.yml", Yaml::encode($info));
|
||||
}
|
||||
// Install the first distribution.
|
||||
$this->profile = 'distribution_one';
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Verify that the distribution name appears.
|
||||
$this->assertRaw('distribution_one');
|
||||
// Verify that the requested theme is used.
|
||||
$this->assertRaw('bartik');
|
||||
// Verify that the "Choose profile" step does not appear.
|
||||
$this->assertNoText('profile');
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
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->rootUser->getUsername());
|
||||
|
||||
// Confirm that Drupal recognizes this distribution as the current profile.
|
||||
$this->assertEqual(\Drupal::installProfile(), 'distribution_one');
|
||||
$this->assertEqual(Settings::get('install_profile'), 'distribution_one', 'The install profile has been written to settings.php.');
|
||||
$this->assertEqual($this->config('core.extension')->get('profile'), 'distribution_one', 'The install profile has been written to core.extension configuration.');
|
||||
|
||||
$this->rebuildContainer();
|
||||
$this->pass('Container can be rebuilt as distribution is written to configuration.');
|
||||
$this->assertEqual(\Drupal::installProfile(), 'distribution_one');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Update;
|
||||
|
||||
use Drupal\Core\Site\Settings;
|
||||
|
||||
/**
|
||||
* Tests system_update_8300().
|
||||
*
|
||||
* @group Update
|
||||
*/
|
||||
class InstallProfileSystemInstall8300Test extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the system_update_8300() runs as expected.
|
||||
*/
|
||||
public function testUpdate() {
|
||||
// Ensure the BC layers work and settings.php and configuration is in the
|
||||
// expected state before updating.
|
||||
$this->assertEqual('standard', \Drupal::installProfile());
|
||||
$this->assertEqual('standard', Settings::get('install_profile'), 'The install profile has not been written to settings.php.');
|
||||
$this->assertFalse($this->config('core.extension')->get('profile'), 'The install profile is not present in core.extension configuration.');
|
||||
|
||||
$this->runUpdates();
|
||||
// Confirm that Drupal recognizes this distribution as the current profile.
|
||||
$this->assertEqual('standard', \Drupal::installProfile());
|
||||
$this->assertEqual('standard', Settings::get('install_profile'), 'The install profile has not been written to settings.php.');
|
||||
$this->assertEqual('standard', $this->config('core.extension')->get('profile'), 'The install profile has been written to core.extension configuration.');
|
||||
}
|
||||
|
||||
}
|
|
@ -1799,6 +1799,15 @@ function system_update_8300() {
|
|||
->save(TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add install profile to core.extension configuration.
|
||||
*/
|
||||
function system_update_8301() {
|
||||
\Drupal::configFactory()->getEditable('core.extension')
|
||||
->set('profile', \Drupal::installProfile())
|
||||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup updates-8.3.0".
|
||||
*/
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\KernelTests\Core\Bootstrap;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
|
@ -16,15 +17,19 @@ class GetFilenameTest extends KernelTestBase {
|
|||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function register(ContainerBuilder $container) {
|
||||
parent::register($container);
|
||||
// Use the testing install profile.
|
||||
$container->setParameter('install_profile', 'testing');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that drupal_get_filename() works when the file is not in database.
|
||||
*/
|
||||
function testDrupalGetFilename() {
|
||||
// drupal_get_profile() is using obtaining the profile from state if the
|
||||
// install_state global is not set.
|
||||
global $install_state;
|
||||
$install_state['parameters']['profile'] = 'testing';
|
||||
|
||||
// Rebuild system.module.files state data.
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491
|
||||
drupal_static_reset('system_rebuild_module_data');
|
||||
|
|
|
@ -668,6 +668,34 @@ class ConfigImporterTest extends KernelTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests install profile validation during configuration import.
|
||||
*
|
||||
* @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber
|
||||
*/
|
||||
public function testInstallProfileMisMatch() {
|
||||
$sync = $this->container->get('config.storage.sync');
|
||||
|
||||
$extensions = $sync->read('core.extension');
|
||||
// Change the install profile.
|
||||
$extensions['profile'] = 'this_will_not_work';
|
||||
$sync->write('core.extension', $extensions);
|
||||
|
||||
try {
|
||||
$this->configImporter->reset()->import();
|
||||
$this->fail('ConfigImporterException not thrown; an invalid import was not stopped due to missing dependencies.');
|
||||
}
|
||||
catch (ConfigImporterException $e) {
|
||||
$this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
|
||||
$error_log = $this->configImporter->getErrors();
|
||||
// Install profiles can not be changed. Note that KernelTestBase currently
|
||||
// does not use an install profile. This situation should be impossible
|
||||
// to get in but site's can removed the install profile setting from
|
||||
// settings.php so the test is valid.
|
||||
$this->assertEqual(['Cannot change the install profile from <em class="placeholder">this_will_not_work</em> to <em class="placeholder"></em> once Drupal is installed.'], $error_log);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests config_get_config_directory().
|
||||
*/
|
||||
|
|
|
@ -392,6 +392,7 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser
|
|||
$this->container->get('config.storage')->write('core.extension', array(
|
||||
'module' => array_fill_keys($modules, 0),
|
||||
'theme' => array(),
|
||||
'profile' => '',
|
||||
));
|
||||
|
||||
$settings = Settings::getAll();
|
||||
|
|
|
@ -27,6 +27,7 @@ class DefaultConfigTest extends UnitTestCase {
|
|||
$expected = array(
|
||||
'module' => array(),
|
||||
'theme' => array(),
|
||||
'profile' => '',
|
||||
);
|
||||
$this->assertEquals($expected, $config);
|
||||
}
|
||||
|
|
|
@ -270,6 +270,11 @@ $config_directories = array();
|
|||
* by the user.
|
||||
*
|
||||
* @see install_select_profile()
|
||||
*
|
||||
* @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. The
|
||||
* install profile is written to the core.extension configuration. If a
|
||||
* service requires the install profile use the 'install_profile' container
|
||||
* parameter. Functional code can use \Drupal::installProfile().
|
||||
*/
|
||||
# $settings['install_profile'] = '';
|
||||
|
||||
|
|
Loading…
Reference in New Issue