updated core to 8.6.1 via composer
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
table.diff {
|
||||
border-spacing: 4px;
|
||||
margin-bottom: 20px;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
table.diff .diff-context {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Provides date format preview feature.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
(function($, Drupal, drupalSettings) {
|
||||
const dateFormats = drupalSettings.dateFormats;
|
||||
|
||||
/**
|
||||
@@ -17,8 +17,12 @@
|
||||
Drupal.behaviors.dateFormat = {
|
||||
attach(context) {
|
||||
const $context = $(context);
|
||||
const $source = $context.find('[data-drupal-date-formatter="source"]').once('dateFormat');
|
||||
const $target = $context.find('[data-drupal-date-formatter="preview"]').once('dateFormat');
|
||||
const $source = $context
|
||||
.find('[data-drupal-date-formatter="source"]')
|
||||
.once('dateFormat');
|
||||
const $target = $context
|
||||
.find('[data-drupal-date-formatter="preview"]')
|
||||
.once('dateFormat');
|
||||
const $preview = $target.find('em');
|
||||
|
||||
// All elements have to exist.
|
||||
@@ -34,7 +38,10 @@
|
||||
*/
|
||||
function dateFormatHandler(e) {
|
||||
const baseValue = $(e.target).val() || '';
|
||||
const dateString = baseValue.replace(/\\?(.?)/gi, (key, value) => (dateFormats[key] ? dateFormats[key] : value));
|
||||
const dateString = baseValue.replace(
|
||||
/\\?(.?)/gi,
|
||||
(key, value) => (dateFormats[key] ? dateFormats[key] : value),
|
||||
);
|
||||
|
||||
$preview.html(dateString);
|
||||
$target.toggleClass('js-hide', !dateString.length);
|
||||
@@ -43,9 +50,13 @@
|
||||
/**
|
||||
* On given event triggers the date character replacement.
|
||||
*/
|
||||
$source.on('keyup.dateFormat change.dateFormat input.dateFormat', dateFormatHandler)
|
||||
$source
|
||||
.on(
|
||||
'keyup.dateFormat change.dateFormat input.dateFormat',
|
||||
dateFormatHandler,
|
||||
)
|
||||
// Initialize preview.
|
||||
.trigger('keyup');
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal, drupalSettings));
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* System behaviors.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
(function($, Drupal, drupalSettings) {
|
||||
// Cache IDs in an array for ease of use.
|
||||
const ids = [];
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
attach(context) {
|
||||
// List of fields IDs on which to bind the event listener.
|
||||
// Create an array of IDs to use with jQuery.
|
||||
Object.keys(drupalSettings.copyFieldValue || {}).forEach((element) => {
|
||||
Object.keys(drupalSettings.copyFieldValue || {}).forEach(element => {
|
||||
ids.push(element);
|
||||
});
|
||||
|
||||
@@ -31,15 +31,23 @@
|
||||
// Listen to value:copy events on all dependent fields.
|
||||
// We have to use body and not document because of the way jQuery events
|
||||
// bubble up the DOM tree.
|
||||
$('body').once('copy-field-values').on('value:copy', this.valueTargetCopyHandler);
|
||||
$('body')
|
||||
.once('copy-field-values')
|
||||
.on('value:copy', this.valueTargetCopyHandler);
|
||||
// Listen on all source elements.
|
||||
$(`#${ids.join(', #')}`).once('copy-field-values').on('blur', this.valueSourceBlurHandler);
|
||||
$(`#${ids.join(', #')}`)
|
||||
.once('copy-field-values')
|
||||
.on('blur', this.valueSourceBlurHandler);
|
||||
}
|
||||
},
|
||||
detach(context, settings, trigger) {
|
||||
if (trigger === 'unload' && ids.length) {
|
||||
$('body').removeOnce('copy-field-values').off('value:copy');
|
||||
$(`#${ids.join(', #')}`).removeOnce('copy-field-values').off('blur');
|
||||
$('body')
|
||||
.removeOnce('copy-field-values')
|
||||
.off('value:copy');
|
||||
$(`#${ids.join(', #')}`)
|
||||
.removeOnce('copy-field-values')
|
||||
.off('blur');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -73,4 +81,4 @@
|
||||
$(`#${targetIds.join(', #')}`).trigger('value:copy', value);
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal, drupalSettings));
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Module page behaviors.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, debounce) {
|
||||
(function($, Drupal, debounce) {
|
||||
/**
|
||||
* Filters the module list table by a text input search string.
|
||||
*
|
||||
@@ -38,7 +38,9 @@
|
||||
|
||||
function showModuleRow(index, row) {
|
||||
const $row = $(row);
|
||||
const $sources = $row.find('.table-filter-text-source, .module-name, .module-description');
|
||||
const $sources = $row.find(
|
||||
'.table-filter-text-source, .module-name, .module-description',
|
||||
);
|
||||
const textMatch = $sources.text().search(re) !== -1;
|
||||
$row.closest('tr').toggle(textMatch);
|
||||
}
|
||||
@@ -53,25 +55,26 @@
|
||||
// Note that we first open all <details> to be able to use ':visible'.
|
||||
// Mark the <details> elements that were closed before filtering, so
|
||||
// they can be reclosed when filtering is removed.
|
||||
$details.not('[open]').attr('data-drupal-system-state', 'forced-open');
|
||||
$details
|
||||
.not('[open]')
|
||||
.attr('data-drupal-system-state', 'forced-open');
|
||||
|
||||
// Hide the package <details> if they don't have any visible rows.
|
||||
// Note that we first show() all <details> to be able to use ':visible'.
|
||||
$details.attr('open', true).each(hidePackageDetails);
|
||||
|
||||
Drupal.announce(
|
||||
Drupal.t(
|
||||
'!modules modules are available in the modified list.',
|
||||
{ '!modules': $rowsAndDetails.find('tbody tr:visible').length },
|
||||
),
|
||||
Drupal.t('!modules modules are available in the modified list.', {
|
||||
'!modules': $rowsAndDetails.find('tbody tr:visible').length,
|
||||
}),
|
||||
);
|
||||
}
|
||||
else if (searching) {
|
||||
} else if (searching) {
|
||||
searching = false;
|
||||
$rowsAndDetails.show();
|
||||
// Return <details> elements that had been closed before filtering
|
||||
// to a closed state.
|
||||
$details.filter('[data-drupal-system-state="forced-open"]')
|
||||
$details
|
||||
.filter('[data-drupal-system-state="forced-open"]')
|
||||
.removeAttr('data-drupal-system-state')
|
||||
.attr('open', false);
|
||||
}
|
||||
@@ -96,4 +99,4 @@
|
||||
}
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal, Drupal.debounce));
|
||||
})(jQuery, Drupal, Drupal.debounce);
|
||||
|
||||
@@ -43,7 +43,9 @@
|
||||
|
||||
$details.attr('open', true).each(hidePackageDetails);
|
||||
|
||||
Drupal.announce(Drupal.t('!modules modules are available in the modified list.', { '!modules': $rowsAndDetails.find('tbody tr:visible').length }));
|
||||
Drupal.announce(Drupal.t('!modules modules are available in the modified list.', {
|
||||
'!modules': $rowsAndDetails.find('tbody tr:visible').length
|
||||
}));
|
||||
} else if (searching) {
|
||||
searching = false;
|
||||
$rowsAndDetails.show();
|
||||
|
||||
@@ -335,11 +335,11 @@ class DbUpdateController extends ControllerBase {
|
||||
|
||||
// Warn the user if any updates were incompatible.
|
||||
if ($incompatible_updates_exist) {
|
||||
drupal_set_message($this->t('Some of the pending updates cannot be applied because their dependencies were not met.'), 'warning');
|
||||
$this->messenger()->addWarning($this->t('Some of the pending updates cannot be applied because their dependencies were not met.'));
|
||||
}
|
||||
|
||||
if (empty($count)) {
|
||||
drupal_set_message($this->t('No pending updates.'));
|
||||
$this->messenger()->addStatus($this->t('No pending updates.'));
|
||||
unset($build);
|
||||
$build['links'] = [
|
||||
'#theme' => 'links',
|
||||
@@ -524,7 +524,7 @@ class DbUpdateController extends ControllerBase {
|
||||
$build['status_report'] = [
|
||||
'#type' => 'status_report',
|
||||
'#requirements' => $requirements,
|
||||
'#suffix' => $this->t('Check the messages and <a href=":url">try again</a>.', [':url' => $try_again_url])
|
||||
'#suffix' => $this->t('Check the messages and <a href=":url">try again</a>.', [':url' => $try_again_url]),
|
||||
];
|
||||
|
||||
$build['#title'] = $this->t('Requirements problem');
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Drupal\system\Controller;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Component\Utility\Tags;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Entity\EntityAutocompleteMatcher;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
|
||||
@@ -81,7 +80,7 @@ class EntityAutocompleteController extends ControllerBase {
|
||||
// Get the typed string from the URL, if it exists.
|
||||
if ($input = $request->query->get('q')) {
|
||||
$typed_string = Tags::explode($input);
|
||||
$typed_string = Unicode::strtolower(array_pop($typed_string));
|
||||
$typed_string = mb_strtolower(array_pop($typed_string));
|
||||
|
||||
// Selection settings are passed in as a hashed key of a serialized array
|
||||
// stored in the key/value store.
|
||||
|
||||
@@ -100,7 +100,7 @@ class SystemController extends ControllerBase {
|
||||
public function overview($link_id) {
|
||||
// Check for status report errors.
|
||||
if ($this->systemManager->checkRequirements() && $this->currentUser()->hasPermission('administer site configuration')) {
|
||||
drupal_set_message($this->t('One or more problems were detected with your Drupal installation. Check the <a href=":status">status report</a> for more information.', [':status' => $this->url('system.status')]), 'error');
|
||||
$this->messenger()->addError($this->t('One or more problems were detected with your Drupal installation. Check the <a href=":status">status report</a> for more information.', [':status' => $this->url('system.status')]));
|
||||
}
|
||||
// Load all menu links below it.
|
||||
$parameters = new MenuTreeParameters();
|
||||
@@ -187,7 +187,7 @@ class SystemController extends ControllerBase {
|
||||
uasort($themes, 'system_sort_modules_by_info_name');
|
||||
|
||||
$theme_default = $config->get('default');
|
||||
$theme_groups = ['installed' => [], 'uninstalled' => []];
|
||||
$theme_groups = ['installed' => [], 'uninstalled' => []];
|
||||
$admin_theme = $config->get('admin');
|
||||
$admin_theme_options = [];
|
||||
|
||||
|
||||
@@ -71,15 +71,15 @@ class ThemeController extends ControllerBase {
|
||||
if (!empty($themes[$theme])) {
|
||||
// Do not uninstall the default or admin theme.
|
||||
if ($theme === $config->get('default') || $theme === $config->get('admin')) {
|
||||
drupal_set_message($this->t('%theme is the default theme and cannot be uninstalled.', ['%theme' => $themes[$theme]->info['name']]), 'error');
|
||||
$this->messenger()->addError($this->t('%theme is the default theme and cannot be uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
|
||||
}
|
||||
else {
|
||||
$this->themeHandler->uninstall([$theme]);
|
||||
drupal_set_message($this->t('The %theme theme has been uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
|
||||
$this->messenger()->addStatus($this->t('The %theme theme has been uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error');
|
||||
$this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
|
||||
}
|
||||
|
||||
return $this->redirect('system.themes_page');
|
||||
@@ -108,15 +108,15 @@ class ThemeController extends ControllerBase {
|
||||
try {
|
||||
if ($this->themeHandler->install([$theme])) {
|
||||
$themes = $this->themeHandler->listInfo();
|
||||
drupal_set_message($this->t('The %theme theme has been installed.', ['%theme' => $themes[$theme]->info['name']]));
|
||||
$this->messenger()->addStatus($this->t('The %theme theme has been installed.', ['%theme' => $themes[$theme]->info['name']]));
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error');
|
||||
$this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
|
||||
}
|
||||
}
|
||||
catch (PreExistingConfigException $e) {
|
||||
$config_objects = $e->flattenConfigObjects($e->getConfigObjects());
|
||||
drupal_set_message(
|
||||
$this->messenger()->addError(
|
||||
$this->formatPlural(
|
||||
count($config_objects),
|
||||
'Unable to install @extension, %config_names already exists in active configuration.',
|
||||
@@ -124,12 +124,11 @@ class ThemeController extends ControllerBase {
|
||||
[
|
||||
'%config_names' => implode(', ', $config_objects),
|
||||
'@extension' => $theme,
|
||||
]),
|
||||
'error'
|
||||
])
|
||||
);
|
||||
}
|
||||
catch (UnmetDependenciesException $e) {
|
||||
drupal_set_message($e->getTranslatedMessage($this->getStringTranslation(), $theme), 'error');
|
||||
$this->messenger()->addError($e->getTranslatedMessage($this->getStringTranslation(), $theme));
|
||||
}
|
||||
|
||||
return $this->redirect('system.themes_page');
|
||||
@@ -171,17 +170,18 @@ class ThemeController extends ControllerBase {
|
||||
// theme.
|
||||
$admin_theme = $config->get('admin');
|
||||
if ($admin_theme != 0 && $admin_theme != $theme) {
|
||||
drupal_set_message($this->t('Please note that the administration theme is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', [
|
||||
'%admin_theme' => $themes[$admin_theme]->info['name'],
|
||||
'%selected_theme' => $themes[$theme]->info['name'],
|
||||
]));
|
||||
$this->messenger()
|
||||
->addStatus($this->t('Please note that the administration theme is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', [
|
||||
'%admin_theme' => $themes[$admin_theme]->info['name'],
|
||||
'%selected_theme' => $themes[$theme]->info['name'],
|
||||
]));
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('%theme is now the default theme.', ['%theme' => $themes[$theme]->info['name']]));
|
||||
$this->messenger()->addStatus($this->t('%theme is now the default theme.', ['%theme' => $themes[$theme]->info['name']]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error');
|
||||
$this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
|
||||
}
|
||||
|
||||
return $this->redirect('system.themes_page');
|
||||
|
||||
@@ -36,7 +36,6 @@ class CronController extends ControllerBase {
|
||||
return new static($container->get('cron'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run Cron once.
|
||||
*
|
||||
@@ -58,10 +57,10 @@ class CronController extends ControllerBase {
|
||||
*/
|
||||
public function runManually() {
|
||||
if ($this->cron->run()) {
|
||||
drupal_set_message($this->t('Cron ran successfully.'));
|
||||
$this->messenger()->addStatus($this->t('Cron ran successfully.'));
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('Cron run failed.'), 'error');
|
||||
$this->messenger()->addError($this->t('Cron run failed.'));
|
||||
}
|
||||
|
||||
return $this->redirect('system.status');
|
||||
|
||||
@@ -15,6 +15,13 @@ use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
* @ConfigEntityType(
|
||||
* id = "action",
|
||||
* label = @Translation("Action"),
|
||||
* label_collection = @Translation("Actions"),
|
||||
* label_singular = @Translation("action"),
|
||||
* label_plural = @Translation("actions"),
|
||||
* label_count = @PluralTranslation(
|
||||
* singular = "@count action",
|
||||
* plural = "@count actions",
|
||||
* ),
|
||||
* admin_permission = "administer actions",
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Drupal\system\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\system\MenuInterface;
|
||||
|
||||
/**
|
||||
@@ -11,6 +12,13 @@ use Drupal\system\MenuInterface;
|
||||
* @ConfigEntityType(
|
||||
* id = "menu",
|
||||
* label = @Translation("Menu"),
|
||||
* label_collection = @Translation("Menus"),
|
||||
* label_singular = @Translation("menu"),
|
||||
* label_plural = @Translation("menus"),
|
||||
* label_count = @PluralTranslation(
|
||||
* singular = "@count menu",
|
||||
* plural = "@count menus",
|
||||
* ),
|
||||
* handlers = {
|
||||
* "access" = "Drupal\system\MenuAccessControlHandler"
|
||||
* },
|
||||
@@ -71,4 +79,43 @@ class Menu extends ConfigEntityBase implements MenuInterface {
|
||||
return (bool) $this->locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function preDelete(EntityStorageInterface $storage, array $entities) {
|
||||
parent::preDelete($storage, $entities);
|
||||
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
|
||||
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
|
||||
foreach ($entities as $menu) {
|
||||
// Delete all links from the menu.
|
||||
$menu_link_manager->deleteLinksInMenu($menu->id());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save() {
|
||||
$return = parent::save();
|
||||
\Drupal::cache('menu')->invalidateAll();
|
||||
// Invalidate the block cache to update menu-based derivatives.
|
||||
if (\Drupal::moduleHandler()->moduleExists('block')) {
|
||||
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete() {
|
||||
parent::delete();
|
||||
\Drupal::cache('menu')->invalidateAll();
|
||||
|
||||
// Invalidate the block cache to update menu-based derivatives.
|
||||
if (\Drupal::moduleHandler()->moduleExists('block')) {
|
||||
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ class CronForm extends FormBase {
|
||||
$this->config('system.cron')
|
||||
->set('logging', $form_state->getValue('logging'))
|
||||
->save();
|
||||
drupal_set_message(t('The configuration options have been saved.'));
|
||||
$this->messenger()->addStatus(t('The configuration options have been saved.'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,10 +163,10 @@ class CronForm extends FormBase {
|
||||
*/
|
||||
public function runCron(array &$form, FormStateInterface $form_state) {
|
||||
if ($this->cron->run()) {
|
||||
drupal_set_message($this->t('Cron ran successfully.'));
|
||||
$this->messenger()->addStatus($this->t('Cron ran successfully.'));
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('Cron run failed.'), 'error');
|
||||
$this->messenger()->addError($this->t('Cron run failed.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ abstract class DateFormatFormBase extends EntityForm {
|
||||
$pattern = trim($form_state->getValue('date_format_pattern'));
|
||||
foreach ($this->dateFormatStorage->loadMultiple() as $format) {
|
||||
if ($format->getPattern() == $pattern && ($format->id() == $this->entity->id())) {
|
||||
drupal_set_message(t('The existing format/name combination has not been altered.'));
|
||||
$this->messenger()->addStatus($this->t('The existing format/name combination has not been altered.'));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -149,10 +149,10 @@ abstract class DateFormatFormBase extends EntityForm {
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
$status = $this->entity->save();
|
||||
if ($status == SAVED_UPDATED) {
|
||||
drupal_set_message(t('Custom date format updated.'));
|
||||
$this->messenger()->addStatus($this->t('Custom date format updated.'));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Custom date format added.'));
|
||||
$this->messenger()->addStatus($this->t('Custom date format added.'));
|
||||
}
|
||||
$form_state->setRedirectUrl($this->entity->urlInfo('collection'));
|
||||
}
|
||||
|
||||
@@ -174,29 +174,27 @@ class ModulesListConfirmForm extends ConfirmFormBase {
|
||||
}
|
||||
catch (PreExistingConfigException $e) {
|
||||
$config_objects = $e->flattenConfigObjects($e->getConfigObjects());
|
||||
drupal_set_message(
|
||||
$this->messenger()->addError(
|
||||
$this->formatPlural(
|
||||
count($config_objects),
|
||||
'Unable to install @extension, %config_names already exists in active configuration.',
|
||||
'Unable to install @extension, %config_names already exist in active configuration.',
|
||||
[
|
||||
'%config_names' => implode(', ', $config_objects),
|
||||
'@extension' => $this->modules['install'][$e->getExtension()]
|
||||
]),
|
||||
'error'
|
||||
'@extension' => $this->modules['install'][$e->getExtension()],
|
||||
])
|
||||
);
|
||||
return;
|
||||
}
|
||||
catch (UnmetDependenciesException $e) {
|
||||
drupal_set_message(
|
||||
$e->getTranslatedMessage($this->getStringTranslation(), $this->modules['install'][$e->getExtension()]),
|
||||
'error'
|
||||
$this->messenger()->addError(
|
||||
$e->getTranslatedMessage($this->getStringTranslation(), $this->modules['install'][$e->getExtension()])
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$module_names = array_values($this->modules['install']);
|
||||
drupal_set_message($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', [
|
||||
$this->messenger()->addStatus($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', [
|
||||
'%name' => $module_names[0],
|
||||
'%names' => implode(', ', $module_names),
|
||||
]));
|
||||
|
||||
@@ -27,7 +27,7 @@ class ModulesListExperimentalConfirmForm extends ModulesListConfirmForm {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildMessageList() {
|
||||
drupal_set_message($this->t('<a href=":url">Experimental modules</a> are provided for testing purposes only. Use at your own risk.', [':url' => 'https://www.drupal.org/core/experimental']), 'warning');
|
||||
$this->messenger()->addWarning($this->t('<a href=":url">Experimental modules</a> are provided for testing purposes only. Use at your own risk.', [':url' => 'https://www.drupal.org/core/experimental']));
|
||||
|
||||
$items = parent::buildMessageList();
|
||||
// Add the list of experimental modules after any other messages.
|
||||
|
||||
@@ -450,30 +450,28 @@ class ModulesListForm extends FormBase {
|
||||
try {
|
||||
$this->moduleInstaller->install(array_keys($modules['install']));
|
||||
$module_names = array_values($modules['install']);
|
||||
drupal_set_message($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', [
|
||||
$this->messenger()->addStatus($this->formatPlural(count($module_names), 'Module %name has been enabled.', '@count modules have been enabled: %names.', [
|
||||
'%name' => $module_names[0],
|
||||
'%names' => implode(', ', $module_names),
|
||||
]));
|
||||
}
|
||||
catch (PreExistingConfigException $e) {
|
||||
$config_objects = $e->flattenConfigObjects($e->getConfigObjects());
|
||||
drupal_set_message(
|
||||
$this->messenger()->addError(
|
||||
$this->formatPlural(
|
||||
count($config_objects),
|
||||
'Unable to install @extension, %config_names already exists in active configuration.',
|
||||
'Unable to install @extension, %config_names already exist in active configuration.',
|
||||
[
|
||||
'%config_names' => implode(', ', $config_objects),
|
||||
'@extension' => $modules['install'][$e->getExtension()]
|
||||
]),
|
||||
'error'
|
||||
'@extension' => $modules['install'][$e->getExtension()],
|
||||
])
|
||||
);
|
||||
return;
|
||||
}
|
||||
catch (UnmetDependenciesException $e) {
|
||||
drupal_set_message(
|
||||
$e->getTranslatedMessage($this->getStringTranslation(), $modules['install'][$e->getExtension()]),
|
||||
'error'
|
||||
$this->messenger()->addError(
|
||||
$e->getTranslatedMessage($this->getStringTranslation(), $modules['install'][$e->getExtension()])
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase {
|
||||
|
||||
// Prevent this page from showing when the module list is empty.
|
||||
if (empty($this->modules)) {
|
||||
drupal_set_message($this->t('The selected modules could not be uninstalled, either due to a website problem or due to the uninstall confirmation form timing out. Please try again.'), 'error');
|
||||
$this->messenger()->addError($this->t('The selected modules could not be uninstalled, either due to a website problem or due to the uninstall confirmation form timing out. Please try again.'));
|
||||
return $this->redirect('system.modules_uninstall');
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase {
|
||||
// Uninstall the modules.
|
||||
$this->moduleInstaller->uninstall($this->modules);
|
||||
|
||||
drupal_set_message($this->t('The selected modules have been uninstalled.'));
|
||||
$this->messenger()->addStatus($this->t('The selected modules have been uninstalled.'));
|
||||
$form_state->setRedirectUrl($this->getCancelUrl());
|
||||
}
|
||||
|
||||
|
||||
@@ -116,8 +116,6 @@ class ModulesUninstallForm extends FormBase {
|
||||
return $form;
|
||||
}
|
||||
|
||||
$profile = drupal_get_profile();
|
||||
|
||||
// Sort all modules by their name.
|
||||
uasort($uninstallable, 'system_sort_modules_by_info_name');
|
||||
$validation_reasons = $this->moduleInstaller->validateUninstall(array_keys($uninstallable));
|
||||
@@ -142,10 +140,9 @@ class ModulesUninstallForm extends FormBase {
|
||||
$form['uninstall'][$module->getName()]['#disabled'] = TRUE;
|
||||
}
|
||||
// All modules which depend on this one must be uninstalled first, before
|
||||
// we can allow this module to be uninstalled. (The installation profile
|
||||
// is excluded from this list.)
|
||||
// we can allow this module to be uninstalled.
|
||||
foreach (array_keys($module->required_by) as $dependent) {
|
||||
if ($dependent != $profile && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
|
||||
if (drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
|
||||
$name = isset($modules[$dependent]->info['name']) ? $modules[$dependent]->info['name'] : $dependent;
|
||||
$form['modules'][$module->getName()]['#required_by'][] = $name;
|
||||
$form['uninstall'][$module->getName()]['#disabled'] = TRUE;
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
namespace Drupal\system\Form;
|
||||
|
||||
use Drupal\Core\Asset\AssetCollectionOptimizerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\ConfigFormBase;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
@@ -37,6 +39,13 @@ class PerformanceForm extends ConfigFormBase {
|
||||
*/
|
||||
protected $jsCollectionOptimizer;
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a PerformanceForm object.
|
||||
*
|
||||
@@ -48,13 +57,16 @@ class PerformanceForm extends ConfigFormBase {
|
||||
* The CSS asset collection optimizer service.
|
||||
* @param \Drupal\Core\Asset\AssetCollectionOptimizerInterface $js_collection_optimizer
|
||||
* The JavaScript asset collection optimizer service.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
*/
|
||||
public function __construct(ConfigFactoryInterface $config_factory, DateFormatterInterface $date_formatter, AssetCollectionOptimizerInterface $css_collection_optimizer, AssetCollectionOptimizerInterface $js_collection_optimizer) {
|
||||
public function __construct(ConfigFactoryInterface $config_factory, DateFormatterInterface $date_formatter, AssetCollectionOptimizerInterface $css_collection_optimizer, AssetCollectionOptimizerInterface $js_collection_optimizer, ModuleHandlerInterface $module_handler) {
|
||||
parent::__construct($config_factory);
|
||||
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->cssCollectionOptimizer = $css_collection_optimizer;
|
||||
$this->jsCollectionOptimizer = $js_collection_optimizer;
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +77,8 @@ class PerformanceForm extends ConfigFormBase {
|
||||
$container->get('config.factory'),
|
||||
$container->get('date.formatter'),
|
||||
$container->get('asset.css.collection_optimizer'),
|
||||
$container->get('asset.js.collection_optimizer')
|
||||
$container->get('asset.js.collection_optimizer'),
|
||||
$container->get('module_handler')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -107,7 +120,6 @@ class PerformanceForm extends ConfigFormBase {
|
||||
'#type' => 'details',
|
||||
'#title' => t('Caching'),
|
||||
'#open' => TRUE,
|
||||
'#description' => $this->t('Note: Drupal provides an internal page cache module that is recommended for small to medium-sized websites.'),
|
||||
];
|
||||
// Identical options to the ones for block caching.
|
||||
// @see \Drupal\Core\Block\BlockBase::buildConfigurationForm()
|
||||
@@ -116,10 +128,14 @@ class PerformanceForm extends ConfigFormBase {
|
||||
$period[0] = '<' . t('no caching') . '>';
|
||||
$form['caching']['page_cache_maximum_age'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => t('Page cache maximum age'),
|
||||
'#title' => t('Browser and proxy cache maximum age'),
|
||||
'#default_value' => $config->get('cache.page.max_age'),
|
||||
'#options' => $period,
|
||||
'#description' => t('The maximum time a page can be cached by browsers and proxies. This is used as the value for max-age in Cache-Control headers.'),
|
||||
'#description' => t('This is used as the value for max-age in Cache-Control headers.'),
|
||||
];
|
||||
$form['caching']['internal_page_cache'] = [
|
||||
'#markup' => $this->t('Drupal provides an <a href=":module_enable">Internal Page Cache module</a> that is recommended for small to medium-sized websites.', [':module_enable' => Url::fromRoute('system.modules_list')->toString()]),
|
||||
'#access' => !$this->moduleHandler->moduleExists('page_cache'),
|
||||
];
|
||||
|
||||
$directory = 'public://';
|
||||
@@ -174,7 +190,7 @@ class PerformanceForm extends ConfigFormBase {
|
||||
*/
|
||||
public function submitCacheClear(array &$form, FormStateInterface $form_state) {
|
||||
drupal_flush_all_caches();
|
||||
drupal_set_message(t('Caches cleared.'));
|
||||
$this->messenger()->addStatus($this->t('Caches cleared.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ class PrepareModulesEntityUninstallForm extends ConfirmFormBase {
|
||||
'@entity_type_singular' => $entity_type->getSingularLabel(),
|
||||
'@entity_type_plural' => $entity_type->getPluralLabel(),
|
||||
]
|
||||
)
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ class PrepareModulesEntityUninstallForm extends ConfirmFormBase {
|
||||
*/
|
||||
public static function moduleBatchFinished($success, $results, $operations) {
|
||||
$entity_type_plural = \Drupal::entityTypeManager()->getDefinition($results['entity_type_id'])->getPluralLabel();
|
||||
drupal_set_message(t('All @entity_type_plural have been deleted.', ['@entity_type_plural' => $entity_type_plural]));
|
||||
\Drupal::messenger()->addStatus(t('All @entity_type_plural have been deleted.', ['@entity_type_plural' => $entity_type_plural]));
|
||||
|
||||
return new RedirectResponse(Url::fromRoute('system.modules_uninstall')->setAbsolute()->toString());
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ class RegionalForm extends ConfigFormBase {
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Remind users at login if their time zone is not set'),
|
||||
'#default_value' => $system_date->get('timezone.user.warn'),
|
||||
'#description' => t('Only applied if users may set their own time zone.')
|
||||
'#description' => t('Only applied if users may set their own time zone.'),
|
||||
];
|
||||
|
||||
$form['timezone']['configurable_timezones_wrapper']['user_default_timezone'] = [
|
||||
@@ -137,7 +137,7 @@ class RegionalForm extends ConfigFormBase {
|
||||
DRUPAL_USER_TIMEZONE_EMPTY => t('Empty time zone'),
|
||||
DRUPAL_USER_TIMEZONE_SELECT => t('Users may set their own time zone at registration'),
|
||||
],
|
||||
'#description' => t('Only applied if users may set their own time zone.')
|
||||
'#description' => t('Only applied if users may set their own time zone.'),
|
||||
];
|
||||
|
||||
return parent::buildForm($form, $form_state);
|
||||
|
||||
@@ -35,7 +35,7 @@ class RssFeedsForm extends ConfigFormBase {
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Feed description'),
|
||||
'#default_value' => $rss_config->get('channel.description'),
|
||||
'#description' => t('Description of your site, included in each feed.')
|
||||
'#description' => t('Description of your site, included in each feed.'),
|
||||
];
|
||||
$options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30];
|
||||
$form['feed_default_items'] = [
|
||||
@@ -43,7 +43,7 @@ class RssFeedsForm extends ConfigFormBase {
|
||||
'#title' => t('Number of items in each feed'),
|
||||
'#default_value' => $rss_config->get('items.limit'),
|
||||
'#options' => array_combine($options, $options),
|
||||
'#description' => t('Default number of items to include in each feed.')
|
||||
'#description' => t('Default number of items to include in each feed.'),
|
||||
];
|
||||
$form['feed_view_mode'] = [
|
||||
'#type' => 'select',
|
||||
@@ -54,7 +54,7 @@ class RssFeedsForm extends ConfigFormBase {
|
||||
'teaser' => t('Titles plus teaser'),
|
||||
'fulltext' => t('Full text'),
|
||||
],
|
||||
'#description' => t('Global setting for the default display of content items in each feed.')
|
||||
'#description' => t('Global setting for the default display of content items in each feed.'),
|
||||
];
|
||||
|
||||
return parent::buildForm($form, $form_state);
|
||||
|
||||
@@ -56,6 +56,7 @@ class SiteMaintenanceModeForm extends ConfigFormBase {
|
||||
$container->get('user.permissions')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -136,11 +136,11 @@ class ThemeSettingsForm extends ConfigFormBase {
|
||||
|
||||
$form['var'] = [
|
||||
'#type' => 'hidden',
|
||||
'#value' => $var
|
||||
'#value' => $var,
|
||||
];
|
||||
$form['config_key'] = [
|
||||
'#type' => 'hidden',
|
||||
'#value' => $config_key
|
||||
'#value' => $config_key,
|
||||
];
|
||||
|
||||
// Toggle settings
|
||||
@@ -377,22 +377,23 @@ class ThemeSettingsForm extends ConfigFormBase {
|
||||
parent::validateForm($form, $form_state);
|
||||
|
||||
if ($this->moduleHandler->moduleExists('file')) {
|
||||
$validators = ['file_validate_is_image' => []];
|
||||
|
||||
// Check for a new uploaded logo.
|
||||
$file = _file_save_upload_from_form($form['logo']['settings']['logo_upload'], $form_state, 0);
|
||||
if ($file) {
|
||||
// Put the temporary file in form_values so we can save it on submit.
|
||||
$form_state->setValue('logo_upload', $file);
|
||||
if (isset($form['logo'])) {
|
||||
$file = _file_save_upload_from_form($form['logo']['settings']['logo_upload'], $form_state, 0);
|
||||
if ($file) {
|
||||
// Put the temporary file in form_values so we can save it on submit.
|
||||
$form_state->setValue('logo_upload', $file);
|
||||
}
|
||||
}
|
||||
|
||||
$validators = ['file_validate_extensions' => ['ico png gif jpg jpeg apng svg']];
|
||||
|
||||
// Check for a new uploaded favicon.
|
||||
$file = _file_save_upload_from_form($form['favicon']['settings']['favicon_upload'], $form_state, 0);
|
||||
if ($file) {
|
||||
// Put the temporary file in form_values so we can save it on submit.
|
||||
$form_state->setValue('favicon_upload', $file);
|
||||
if (isset($form['favicon'])) {
|
||||
$file = _file_save_upload_from_form($form['favicon']['settings']['favicon_upload'], $form_state, 0);
|
||||
if ($file) {
|
||||
// Put the temporary file in form_values so we can save it on submit.
|
||||
$form_state->setValue('favicon_upload', $file);
|
||||
}
|
||||
}
|
||||
|
||||
// When intending to use the default logo, unset the logo_path.
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Drupal\system;
|
||||
|
||||
use Drupal\Component\Transliteration\TransliterationInterface;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Access\CsrfTokenGenerator;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
@@ -73,7 +72,7 @@ class MachineNameController implements ContainerInjectionInterface {
|
||||
|
||||
$transliterated = $this->transliteration->transliterate($text, $langcode, '_');
|
||||
if ($lowercase) {
|
||||
$transliterated = Unicode::strtolower($transliterated);
|
||||
$transliterated = mb_strtolower($transliterated);
|
||||
}
|
||||
|
||||
if (isset($replace_pattern) && isset($replace)) {
|
||||
|
||||
@@ -9,7 +9,7 @@ use Drupal\Core\Cache\Cache;
|
||||
/**
|
||||
* Provides a block to display the messages.
|
||||
*
|
||||
* @see drupal_set_message()
|
||||
* @see @see \Drupal\Core\Messenger\MessengerInterface
|
||||
*
|
||||
* @Block(
|
||||
* id = "system_messages_block",
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\system\Plugin\Condition;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Condition\ConditionPluginBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Path\AliasManagerInterface;
|
||||
@@ -139,7 +138,7 @@ class RequestPath extends ConditionPluginBase implements ContainerFactoryPluginI
|
||||
public function evaluate() {
|
||||
// Convert path to lowercase. This allows comparison of the same path
|
||||
// with different case. Ex: /Page, /page, /PAGE.
|
||||
$pages = Unicode::strtolower($this->configuration['pages']);
|
||||
$pages = mb_strtolower($this->configuration['pages']);
|
||||
if (!$pages) {
|
||||
return TRUE;
|
||||
}
|
||||
@@ -149,7 +148,7 @@ class RequestPath extends ConditionPluginBase implements ContainerFactoryPluginI
|
||||
$path = $this->currentPath->getPath($request);
|
||||
// Do not trim a trailing slash if that is the complete path.
|
||||
$path = $path === '/' ? $path : rtrim($path, '/');
|
||||
$path_alias = Unicode::strtolower($this->aliasManager->getAliasByPath($path));
|
||||
$path_alias = mb_strtolower($this->aliasManager->getAliasByPath($path));
|
||||
|
||||
return $this->pathMatcher->matchPath($path_alias, $pages) || (($path != $path_alias) && $this->pathMatcher->matchPath($path, $pages));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Drupal\system\Plugin\ImageToolkit;
|
||||
|
||||
use Drupal\Component\Utility\Color;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\ImageToolkit\ImageToolkitBase;
|
||||
@@ -395,7 +394,7 @@ class GDToolkit extends ImageToolkitBase {
|
||||
foreach (static::supportedTypes() as $image_type) {
|
||||
// @todo Automatically fetch possible extensions for each mime type.
|
||||
// @see https://www.drupal.org/node/2311679
|
||||
$extension = Unicode::strtolower(image_type_to_extension($image_type, FALSE));
|
||||
$extension = mb_strtolower(image_type_to_extension($image_type, FALSE));
|
||||
$extensions[] = $extension;
|
||||
// Add some known similar extensions.
|
||||
if ($extension === 'jpeg') {
|
||||
|
||||
@@ -20,6 +20,16 @@ class ScaleAndCrop extends GDImageToolkitOperationBase {
|
||||
*/
|
||||
protected function arguments() {
|
||||
return [
|
||||
'x' => [
|
||||
'description' => 'The horizontal offset for the start of the crop, in pixels',
|
||||
'required' => FALSE,
|
||||
'default' => NULL,
|
||||
],
|
||||
'y' => [
|
||||
'description' => 'The vertical offset for the start the crop, in pixels',
|
||||
'required' => FALSE,
|
||||
'default' => NULL,
|
||||
],
|
||||
'width' => [
|
||||
'description' => 'The target width, in pixels',
|
||||
],
|
||||
@@ -38,8 +48,12 @@ class ScaleAndCrop extends GDImageToolkitOperationBase {
|
||||
|
||||
$scaleFactor = max($arguments['width'] / $actualWidth, $arguments['height'] / $actualHeight);
|
||||
|
||||
$arguments['x'] = (int) round(($actualWidth * $scaleFactor - $arguments['width']) / 2);
|
||||
$arguments['y'] = (int) round(($actualHeight * $scaleFactor - $arguments['height']) / 2);
|
||||
$arguments['x'] = isset($arguments['x']) ?
|
||||
(int) round($arguments['x']) :
|
||||
(int) round(($actualWidth * $scaleFactor - $arguments['width']) / 2);
|
||||
$arguments['y'] = isset($arguments['y']) ?
|
||||
(int) round($arguments['y']) :
|
||||
(int) round(($actualHeight * $scaleFactor - $arguments['height']) / 2);
|
||||
$arguments['resize'] = [
|
||||
'width' => (int) round($actualWidth * $scaleFactor),
|
||||
'height' => (int) round($actualHeight * $scaleFactor),
|
||||
|
||||
@@ -14,6 +14,7 @@ use Drupal\migrate\Row;
|
||||
* )
|
||||
*/
|
||||
class TimeZone extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Gets system data for a legacy extension.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "extension",
|
||||
* source_module = "system"
|
||||
* )
|
||||
*/
|
||||
class Extension extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('system', 's')
|
||||
->fields('s');
|
||||
|
||||
if (isset($this->configuration['name'])) {
|
||||
$query->condition('name', (array) $this->configuration['name'], 'IN');
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = [
|
||||
'filename' => $this->t('Filename'),
|
||||
'name' => $this->t('Name'),
|
||||
'type' => $this->t('Type'),
|
||||
'owner' => $this->t('Owner'),
|
||||
'status' => $this->t('Status'),
|
||||
'throttle' => $this->t('Throttle'),
|
||||
'bootstrap' => $this->t('Bootstrap'),
|
||||
'schema_version' => $this->t('Schema version'),
|
||||
'weight' => $this->t('Weight'),
|
||||
'info' => $this->t('Information array'),
|
||||
];
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
$row->setSourceProperty('info', unserialize($row->getSourceProperty('info')));
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['name']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -72,6 +72,9 @@ class SystemConfigSubscriber implements EventSubscriberInterface {
|
||||
* The config import event.
|
||||
*/
|
||||
public function onConfigImporterValidateSiteUUID(ConfigImporterEvent $event) {
|
||||
if (!$event->getConfigImporter()->getStorageComparer()->getSourceStorage()->exists('system.site')) {
|
||||
$event->getConfigImporter()->logError($this->t('This import does not contain system.site configuration, so has been rejected.'));
|
||||
}
|
||||
if (!$event->getConfigImporter()->getStorageComparer()->validateSiteUuid()) {
|
||||
$event->getConfigImporter()->logError($this->t('Site UUID in source storage does not match the target storage.'));
|
||||
}
|
||||
|
||||
@@ -152,7 +152,8 @@ class SystemManager {
|
||||
* hidden, so we supply the contents of the block.
|
||||
*
|
||||
* @return array
|
||||
* A render array suitable for drupal_render.
|
||||
* A render array suitable for
|
||||
* \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
public function getBlockContents() {
|
||||
// We hard-code the menu name here since otherwise a link in the tools menu
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Ajax;
|
||||
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Tests the usage of form caching for AJAX forms.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class AjaxFormCacheTest extends AjaxTestBase {
|
||||
|
||||
/**
|
||||
* Tests the usage of form cache for AJAX forms.
|
||||
*/
|
||||
public function testFormCacheUsage() {
|
||||
/** @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable */
|
||||
$key_value_expirable = \Drupal::service('keyvalue.expirable')->get('form');
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
// Ensure that the cache is empty.
|
||||
$this->assertEqual(0, count($key_value_expirable->getAll()));
|
||||
|
||||
// Visit an AJAX form that is not cached, 3 times.
|
||||
$uncached_form_url = Url::fromRoute('ajax_forms_test.commands_form');
|
||||
$this->drupalGet($uncached_form_url);
|
||||
$this->drupalGet($uncached_form_url);
|
||||
$this->drupalGet($uncached_form_url);
|
||||
|
||||
// The number of cache entries should not have changed.
|
||||
$this->assertEqual(0, count($key_value_expirable->getAll()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests AJAX forms in blocks.
|
||||
*/
|
||||
public function testBlockForms() {
|
||||
$this->container->get('module_installer')->install(['block', 'search']);
|
||||
$this->rebuildContainer();
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
$this->drupalPlaceBlock('search_form_block', ['weight' => -5]);
|
||||
$this->drupalPlaceBlock('ajax_forms_test_block');
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->drupalPostAjaxForm(NULL, ['test1' => 'option1'], 'test1');
|
||||
$this->assertOptionSelectedWithDrupalSelector('edit-test1', 'option1');
|
||||
$this->assertOptionWithDrupalSelector('edit-test1', 'option3');
|
||||
$this->drupalPostForm(NULL, ['test1' => 'option1'], 'Submit');
|
||||
$this->assertText('Submission successful.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests AJAX forms on pages with a query string.
|
||||
*/
|
||||
public function testQueryString() {
|
||||
$this->container->get('module_installer')->install(['block']);
|
||||
$this->drupalLogin($this->rootUser);
|
||||
|
||||
$this->drupalPlaceBlock('ajax_forms_test_block');
|
||||
|
||||
$url = Url::fromRoute('entity.user.canonical', ['user' => $this->rootUser->id()], ['query' => ['foo' => 'bar']]);
|
||||
$this->drupalGet($url);
|
||||
$this->drupalPostAjaxForm(NULL, ['test1' => 'option1'], 'test1');
|
||||
$url->setOption('query', [
|
||||
'foo' => 'bar',
|
||||
FormBuilderInterface::AJAX_FORM_REQUEST => 1,
|
||||
MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax',
|
||||
]);
|
||||
$this->assertUrl($url);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Ajax;
|
||||
|
||||
/**
|
||||
* Tests that form elements in groups work correctly with AJAX.
|
||||
*
|
||||
* @group Ajax
|
||||
*/
|
||||
class AjaxInGroupTest extends AjaxTestBase {
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser(['access content']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits forms with select and checkbox elements via Ajax.
|
||||
*/
|
||||
public function testSimpleAjaxFormValue() {
|
||||
$this->drupalGet('/ajax_forms_test_get_form');
|
||||
$this->assertText('Test group');
|
||||
$this->assertText('AJAX checkbox in a group');
|
||||
|
||||
$this->drupalPostAjaxForm(NULL, ['checkbox_in_group' => TRUE], 'checkbox_in_group');
|
||||
$this->assertText('Test group');
|
||||
$this->assertText('AJAX checkbox in a group');
|
||||
$this->assertText('AJAX checkbox in a nested group');
|
||||
$this->assertText('Another AJAX checkbox in a nested group');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,6 +29,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
* @group Ajax
|
||||
*/
|
||||
class CommandsTest extends AjaxTestBase {
|
||||
|
||||
/**
|
||||
* Tests the various Ajax Commands.
|
||||
*/
|
||||
|
||||
@@ -114,7 +114,7 @@ class DialogTest extends AjaxTestBase {
|
||||
], [], 'ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog']], [], NULL, [
|
||||
'submit' => [
|
||||
'dialogOptions[target]' => 'ajax-test-dialog-wrapper-1',
|
||||
]
|
||||
],
|
||||
]);
|
||||
$this->assertEqual($normal_expected_response, $ajax_result[3], 'Normal dialog JSON response matches.');
|
||||
|
||||
@@ -126,7 +126,7 @@ class DialogTest extends AjaxTestBase {
|
||||
'textfield' => 'test',
|
||||
], [], 'ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog']], [], NULL, [
|
||||
// Don't send a target.
|
||||
'submit' => []
|
||||
'submit' => [],
|
||||
]);
|
||||
// Make sure the selector ID starts with the right string.
|
||||
$this->assert(strpos($ajax_result[3]['selector'], $no_target_expected_response['selector']) === 0, 'Selector starts with right string.');
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Drupal\system\Tests\Ajax;
|
||||
* @group Ajax
|
||||
*/
|
||||
class ElementValidationTest extends AjaxTestBase {
|
||||
|
||||
/**
|
||||
* Tries to post an Ajax change to a form that has a validated element.
|
||||
*
|
||||
|
||||
@@ -10,6 +10,7 @@ use Drupal\Core\Ajax\DataCommand;
|
||||
* @group Ajax
|
||||
*/
|
||||
class FormValuesTest extends AjaxTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ use Drupal\Core\Asset\AttachedAssets;
|
||||
* @group Ajax
|
||||
*/
|
||||
class FrameworkTest extends AjaxTestBase {
|
||||
|
||||
/**
|
||||
* Verifies the Ajax rendering of a command in the settings.
|
||||
*/
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Bootstrap;
|
||||
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
|
||||
/**
|
||||
* Container base class which triggers an error.
|
||||
*/
|
||||
class ErrorContainer extends Container {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
if ($id === 'http_kernel') {
|
||||
// Enforce a recoverable error.
|
||||
$callable = function (ErrorContainer $container) {
|
||||
};
|
||||
$callable(1);
|
||||
}
|
||||
else {
|
||||
return parent::get($id, $invalidBehavior);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Bootstrap;
|
||||
|
||||
use Drupal\Core\DependencyInjection\Container;
|
||||
|
||||
/**
|
||||
* Base container which throws an exception.
|
||||
*/
|
||||
class ExceptionContainer extends Container {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE) {
|
||||
if ($id === 'http_kernel') {
|
||||
throw new \Exception('Thrown exception during Container::get');
|
||||
}
|
||||
else {
|
||||
return parent::get($id, $invalidBehavior);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ namespace Drupal\system\Tests\Cache;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
|
||||
/**
|
||||
* Provides helper methods for page cache tags tests.
|
||||
@@ -47,7 +47,7 @@ abstract class PageCacheTagsTestBase extends WebTestBase {
|
||||
*/
|
||||
protected function verifyPageCache(Url $url, $hit_or_miss, $tags = FALSE) {
|
||||
$this->drupalGet($url);
|
||||
$message = SafeMarkup::format('Page cache @hit_or_miss for %path.', ['@hit_or_miss' => $hit_or_miss, '%path' => $url->toString()]);
|
||||
$message = new FormattableMarkup('Page cache @hit_or_miss for %path.', ['@hit_or_miss' => $hit_or_miss, '%path' => $url->toString()]);
|
||||
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), $hit_or_miss, $message);
|
||||
|
||||
if ($hit_or_miss === 'HIT' && is_array($tags)) {
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Common;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests SimpleTest error and exception collector.
|
||||
*
|
||||
* @group Common
|
||||
*/
|
||||
class SimpleTestErrorCollectorTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['system_test', 'error_test'];
|
||||
|
||||
/**
|
||||
* Errors triggered during the test.
|
||||
*
|
||||
* Errors are intercepted by the overridden implementation
|
||||
* of Drupal\simpletest\WebTestBase::error() below.
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
protected $collectedErrors = [];
|
||||
|
||||
/**
|
||||
* Tests that simpletest collects errors from the tested site.
|
||||
*/
|
||||
public function testErrorCollect() {
|
||||
$this->collectedErrors = [];
|
||||
$this->drupalGet('error-test/generate-warnings-with-report');
|
||||
$this->assertEqual(count($this->collectedErrors), 3, 'Three errors were collected');
|
||||
|
||||
if (count($this->collectedErrors) == 3) {
|
||||
$this->assertError($this->collectedErrors[0], 'Notice', 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()', 'ErrorTestController.php', 'Undefined variable: bananas');
|
||||
$this->assertError($this->collectedErrors[1], 'Warning', 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()', 'ErrorTestController.php', 'Division by zero');
|
||||
$this->assertError($this->collectedErrors[2], 'User warning', 'Drupal\error_test\Controller\ErrorTestController->generateWarnings()', 'ErrorTestController.php', 'Drupal & awesome');
|
||||
}
|
||||
else {
|
||||
// Give back the errors to the log report.
|
||||
foreach ($this->collectedErrors as $error) {
|
||||
parent::error($error['message'], $error['group'], $error['caller']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores errors into an array.
|
||||
*
|
||||
* This test class is trying to verify that simpletest correctly sees errors
|
||||
* and warnings. However, it can't generate errors and warnings that
|
||||
* propagate up to the testing framework itself, or these tests would always
|
||||
* fail. So, this special copy of error() doesn't propagate the errors up
|
||||
* the class hierarchy. It just stuffs them into a protected collectedErrors
|
||||
* array for various assertions to inspect.
|
||||
*/
|
||||
protected function error($message = '', $group = 'Other', array $caller = NULL) {
|
||||
// Due to a WTF elsewhere, simpletest treats debug() and verbose()
|
||||
// messages as if they were an 'error'. But, we don't want to collect
|
||||
// those here. This function just wants to collect the real errors (PHP
|
||||
// notices, PHP fatal errors, etc.), and let all the 'errors' from the
|
||||
// 'User notice' group bubble up to the parent classes to be handled (and
|
||||
// eventually displayed) as normal.
|
||||
if ($group == 'User notice') {
|
||||
parent::error($message, $group, $caller);
|
||||
}
|
||||
// Everything else should be collected but not propagated.
|
||||
else {
|
||||
$this->collectedErrors[] = [
|
||||
'message' => $message,
|
||||
'group' => $group,
|
||||
'caller' => $caller
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a collected error matches what we are expecting.
|
||||
*/
|
||||
public function assertError($error, $group, $function, $file, $message = NULL) {
|
||||
$this->assertEqual($error['group'], $group, format_string("Group was %group", ['%group' => $group]));
|
||||
$this->assertEqual($error['caller']['function'], $function, format_string("Function was %function", ['%function' => $function]));
|
||||
$this->assertEqual(drupal_basename($error['caller']['file']), $file, format_string("File was %file", ['%file' => $file]));
|
||||
if (isset($message)) {
|
||||
$this->assertEqual($error['message'], $message, format_string("Message was %message", ['%message' => $message]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,11 +14,15 @@ use Drupal\system\Tests\Cache\PageCacheTagsTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
@trigger_error(__NAMESPACE__ . '\EntityCacheTagsTestBase is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Entity\EntityCacheTagsTestBase. See https://www.drupal.org/node/2946549.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Provides helper methods for Entity cache tags tests.
|
||||
*
|
||||
* @deprecated Scheduled for removal in Drupal 9.0.0.
|
||||
* Use \Drupal\Tests\system\Functional\Entity\EntityCacheTagsTestBase instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2946549
|
||||
*/
|
||||
abstract class EntityCacheTagsTestBase extends PageCacheTagsTestBase {
|
||||
|
||||
|
||||
@@ -5,8 +5,15 @@ namespace Drupal\system\Tests\Entity;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\entity_test\FieldStorageDefinition;
|
||||
|
||||
@trigger_error(__NAMESPACE__ . '\EntityDefinitionTestTrait is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait. See https://www.drupal.org/node/2946549.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Provides some test methods used to update existing entity definitions.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0.
|
||||
* Use \Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2946549
|
||||
*/
|
||||
trait EntityDefinitionTestTrait {
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\system\Tests\Entity;
|
||||
|
||||
@trigger_error(__FILE__ . ' is deprecated in Drupal 8.1.0 and will be removed before Drupal 9.0.0. Use \Drupal\KernelTests\Core\Entity\EntityKernelTestBase instead.', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\user\Entity\Role;
|
||||
@@ -10,7 +12,7 @@ use Drupal\user\Entity\User;
|
||||
/**
|
||||
* Defines an abstract test base for entity unit tests.
|
||||
*
|
||||
* @deprecated in Drupal 8.1.x, will be removed before Drupal 8.2.x. Use
|
||||
* @deprecated in Drupal 8.1.0, will be removed before Drupal 9.0.0. Use
|
||||
* \Drupal\KernelTests\Core\Entity\EntityKernelTestBase instead.
|
||||
*/
|
||||
abstract class EntityUnitTestBase extends KernelTestBase {
|
||||
|
||||
@@ -7,8 +7,15 @@ use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
|
||||
@trigger_error(__NAMESPACE__ . '\EntityWithUriCacheTagsTestBase is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\system\Functional\Entity\EntityWithUriCacheTagsTestBase. See https://www.drupal.org/node/2946549.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Provides helper methods for Entity cache tags tests; for entities with URIs.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0.
|
||||
* Use \Drupal\Tests\system\Functional\Entity\EntityWithUriCacheTagsTestBase.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2946549
|
||||
*/
|
||||
abstract class EntityWithUriCacheTagsTestBase extends EntityCacheTagsTestBase {
|
||||
|
||||
|
||||
@@ -163,7 +163,6 @@ class ElementsTableSelectTest extends WebTestBase {
|
||||
$this->assertNoFieldByXPath('//th[@class="select-all"]', NULL, 'Do not display a "Select all" checkbox when #multiple is FALSE, even when #js_select is TRUE.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the whether the option checker gives an error on invalid tableselect values for checkboxes.
|
||||
*/
|
||||
@@ -187,7 +186,6 @@ class ElementsTableSelectTest extends WebTestBase {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the whether the option checker gives an error on invalid tableselect values for radios.
|
||||
*/
|
||||
@@ -211,7 +209,6 @@ class ElementsTableSelectTest extends WebTestBase {
|
||||
$this->assertTrue(isset($errors['tableselect']), 'Option checker disallows invalid values for radio buttons.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function for the option check test to submit a form while collecting errors.
|
||||
*
|
||||
@@ -248,7 +245,7 @@ class ElementsTableSelectTest extends WebTestBase {
|
||||
$errors = $form_state->getErrors();
|
||||
|
||||
// Clear errors and messages.
|
||||
drupal_get_messages();
|
||||
\Drupal::messenger()->deleteAll();
|
||||
$form_state->clearErrors();
|
||||
|
||||
// Return the processed form together with form_state and errors
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Drupal\system\Tests\Image;
|
||||
@trigger_error(__FILE__ . ' is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use Drupal\FunctionalTests\Image\ToolkitTestBase instead. See https://www.drupal.org/node/2862641.', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
|
||||
/**
|
||||
* Base class for image manipulation testing.
|
||||
@@ -106,10 +106,10 @@ abstract class ToolkitTestBase extends WebTestBase {
|
||||
// Determine if there were any expected that were not called.
|
||||
$uncalled = array_diff($expected, $actual);
|
||||
if (count($uncalled)) {
|
||||
$this->assertTrue(FALSE, SafeMarkup::format('Expected operations %expected to be called but %uncalled was not called.', ['%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)]));
|
||||
$this->assertTrue(FALSE, new FormattableMarkup('Expected operations %expected to be called but %uncalled was not called.', ['%expected' => implode(', ', $expected), '%uncalled' => implode(', ', $uncalled)]));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(TRUE, SafeMarkup::format('All the expected operations were called: %expected', ['%expected' => implode(', ', $expected)]));
|
||||
$this->assertTrue(TRUE, new FormattableMarkup('All the expected operations were called: %expected', ['%expected' => implode(', ', $expected)]));
|
||||
}
|
||||
|
||||
// Determine if there were any unexpected calls.
|
||||
@@ -117,7 +117,7 @@ abstract class ToolkitTestBase extends WebTestBase {
|
||||
// count it as an error.
|
||||
$unexpected = array_diff($actual, $expected);
|
||||
if (count($unexpected) && (!in_array('apply', $expected) || count(array_intersect($unexpected, $operations)) !== count($unexpected))) {
|
||||
$this->assertTrue(FALSE, SafeMarkup::format('Unexpected operations were called: %unexpected.', ['%unexpected' => implode(', ', $unexpected)]));
|
||||
$this->assertTrue(FALSE, new FormattableMarkup('Unexpected operations were called: %unexpected.', ['%unexpected' => implode(', ', $unexpected)]));
|
||||
}
|
||||
else {
|
||||
$this->assertTrue(TRUE, 'No unexpected operations were called.');
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
@trigger_error(__NAMESPACE__ . '\ConfigAfterInstallerTestBase is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\FunctionalTests\Installer\ConfigAfterInstallerTestBase.', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\Core\Config\FileStorage;
|
||||
use Drupal\Core\Config\InstallStorage;
|
||||
use Drupal\Core\Config\StorageInterface;
|
||||
@@ -10,6 +12,9 @@ use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Provides a class for install profiles to check their installed config.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0.
|
||||
* Use \Drupal\FunctionalTests\Installer\ConfigAfterInstallerTestBase.
|
||||
*/
|
||||
abstract class ConfigAfterInstallerTestBase extends InstallerTestBase {
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
<?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');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class DistributionProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The distribution profile info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $info;
|
||||
|
||||
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));
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Verify that the distribution name appears.
|
||||
$this->assertRaw($this->info['distribution']['name']);
|
||||
// Verify that the distribution name is used in the site title.
|
||||
$this->assertTitle('Choose language | ' . $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.
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->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.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support with a 'langcode' query string.
|
||||
*
|
||||
* @group Installer
|
||||
*
|
||||
* @see \Drupal\system\Tests\Installer\DistributionProfileTranslationTest
|
||||
*/
|
||||
class DistributionProfileTranslationQueryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* 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',
|
||||
'langcode' => $this->langcode,
|
||||
'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));
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.fr.po', $this->getPo('fr'));
|
||||
|
||||
// Pass a different language code than the one set in the distribution
|
||||
// profile. This distribution language should still be used.
|
||||
// The unrouted URL assembler does not exist at this point, so we build the
|
||||
// URL ourselves.
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php' . '?langcode=fr');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because the distribution profile uses a fixed
|
||||
// language.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// The language should have been automatically detected, all following
|
||||
// screens should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual((string) current($elements), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = (string) current($this->xpath('/html/@dir'));
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
|
||||
// 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::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->getDisplayName());
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*
|
||||
* @see \Drupal\system\Tests\Installer\DistributionProfileTest
|
||||
*/
|
||||
class DistributionProfileTranslationTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* 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',
|
||||
'langcode' => $this->langcode,
|
||||
'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));
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
|
||||
parent::visitInstaller();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// This step is skipped, because the distribution profile uses a fixed
|
||||
// language.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is a distribution profile.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// The language should have been automatically detected, all following
|
||||
// screens should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual((string) current($elements), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = (string) current($this->xpath('/html/@dir'));
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
|
||||
// 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::setUpSettings();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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->getDisplayName());
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installer when a config_directory set up but does not exist.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerConfigDirectorySetNoDirectoryErrorTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The directory where the sync directory should be created during install.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $configDirectory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->configDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64();
|
||||
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
|
||||
'value' => $this->configDirectory . '/sync',
|
||||
'required' => TRUE,
|
||||
];
|
||||
// Create the files directory early so we can test the error case.
|
||||
mkdir($this->publicFilesDirectory);
|
||||
// Create a file so the directory can not be created.
|
||||
file_put_contents($this->configDirectory, 'Test');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Configure settings.
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// This step should not appear as we had a failure prior to the settings
|
||||
// screen.
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// This step should not appear as we had a failure prior to the settings
|
||||
// screen.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation failed.
|
||||
*/
|
||||
public function testError() {
|
||||
$this->assertText("An automated attempt to create the directory {$this->configDirectory}/sync failed, possibly due to a permissions problem.");
|
||||
$this->assertFalse(file_exists($this->configDirectory . '/sync') && is_dir($this->configDirectory . '/sync'), "The directory {$this->configDirectory}/sync does not exist.");
|
||||
}
|
||||
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installer when a config_directory set up but does not exist.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerConfigDirectorySetNoDirectoryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The sync directory created during the install.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $syncDirectory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->syncDirectory = $this->publicFilesDirectory . '/config_' . Crypt::randomBytesBase64() . '/sync';
|
||||
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
|
||||
'value' => $this->syncDirectory,
|
||||
'required' => TRUE,
|
||||
];
|
||||
// Other directories will be created too.
|
||||
$this->settings['config_directories']['custom'] = (object) [
|
||||
'value' => $this->publicFilesDirectory . '/config_custom',
|
||||
'required' => TRUE,
|
||||
];
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertTrue(file_exists($this->syncDirectory) && is_dir($this->syncDirectory), "The directory {$this->syncDirectory} exists.");
|
||||
$this->assertTrue(file_exists($this->publicFilesDirectory . '/config_custom') && is_dir($this->publicFilesDirectory . '/config_custom'), "The directory {$this->publicFilesDirectory}/custom_config exists.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installer with database errors.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerDatabaseErrorMessagesTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// We are creating a table here to force an error in the installer because
|
||||
// it will try and create the drupal_install_test table as this is part of
|
||||
// the standard database tests performed by the installer in
|
||||
// Drupal\Core\Database\Install\Tasks.
|
||||
Database::getConnection('default')->query('CREATE TABLE {drupal_install_test} (id int NULL)');
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// This step should not appear as we had a failure on the settings screen.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the error message in the settings step is correct.
|
||||
*/
|
||||
public function testSetUpSettingsErrorMessage() {
|
||||
$this->assertRaw('<ul><li>Failed to <strong>CREATE</strong> a test table');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installer with empty settings file.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerEmptySettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
// Create an empty settings.php file.
|
||||
touch($this->siteDirectory . '/settings.php');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installer when a config_directory has already been set up.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingConfigDirectoryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The expected file perms of the folder.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $expectedFilePerms;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
mkdir($this->siteDirectory . '/config_read_only', 0444);
|
||||
$this->expectedFilePerms = fileperms($this->siteDirectory . '/config_read_only');
|
||||
$this->settings['config_directories'][CONFIG_SYNC_DIRECTORY] = (object) [
|
||||
'value' => $this->siteDirectory . '/config_read_only',
|
||||
'required' => TRUE,
|
||||
];
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
$this->assertEqual($this->expectedFilePerms, fileperms($this->siteDirectory . '/config_read_only'));
|
||||
$this->assertEqual([], glob($this->siteDirectory . '/config_read_only/*'), 'The sync directory is empty after install because it is read-only.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing settings file with database connection
|
||||
* info.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingDatabaseSettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
// Pre-configure database credentials in settings.php.
|
||||
$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,
|
||||
];
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @todo The database settings form is not supposed to appear if settings.php
|
||||
* contains a valid database connection already (but e.g. no config
|
||||
* directories yet).
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// All database settings should be pre-configured, except password.
|
||||
$values = $this->parameters['forms']['install_settings_form'];
|
||||
$driver = $values['driver'];
|
||||
$edit = [];
|
||||
if (isset($values[$driver]['password']) && $values[$driver]['password'] !== '') {
|
||||
$edit = $this->translatePostValues([
|
||||
$driver => [
|
||||
'password' => $values[$driver]['password'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
$this->drupalPostForm(NULL, $edit, $this->translations['Save and continue']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that installation succeeded.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing Drupal installation.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingInstallationTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that Drupal can't be reinstalled while an existing installation is
|
||||
* available.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
// Verify that Drupal can't be immediately reinstalled.
|
||||
$this->visitInstaller();
|
||||
$this->assertRaw('Drupal already installed');
|
||||
|
||||
// Delete settings.php and attempt to reinstall again.
|
||||
unlink($this->siteDirectory . '/settings.php');
|
||||
$this->visitInstaller();
|
||||
$this->setUpLanguage();
|
||||
$this->setUpProfile();
|
||||
$this->setUpRequirementsProblem();
|
||||
$this->setUpSettings();
|
||||
$this->assertRaw('Drupal already installed');
|
||||
}
|
||||
|
||||
}
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
<?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.");
|
||||
}
|
||||
|
||||
}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
<?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) [
|
||||
'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.
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'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');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
<?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 the installer with an existing settings file but no install profile.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingSettingsNoProfileTest 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,
|
||||
];
|
||||
|
||||
// Pre-configure config directories.
|
||||
$this->settings['config_directories'] = [
|
||||
CONFIG_SYNC_DIRECTORY => (object) [
|
||||
'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 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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DrupalKernel;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Tests the installer with an existing settings file.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerExistingSettingsTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Fully configures a preexisting settings.php file 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,
|
||||
];
|
||||
|
||||
// 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 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_sync',
|
||||
'required' => TRUE,
|
||||
],
|
||||
];
|
||||
mkdir($this->settings['config_directories'][CONFIG_SYNC_DIRECTORY]->value, 0777, TRUE);
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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(), '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');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Verifies that the early installer uses the correct language direction.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerLanguageDirectionTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Overrides the language code the installer should use.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'ar';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.ar.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue Arabic\"");
|
||||
|
||||
parent::setUpLanguage();
|
||||
// After selecting a different language than English, all following screens
|
||||
// should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual((string) current($elements), 'Save and continue Arabic');
|
||||
$this->translations['Save and continue'] = 'Save and continue Arabic';
|
||||
|
||||
// Verify that language direction is right-to-left.
|
||||
$direction = (string) current($this->xpath('/html/@dir'));
|
||||
$this->assertEqual($direction, 'rtl');
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Language\LanguageManager;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Verifies that the installer language list combines local and remote languages.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerLanguagePageTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Installer step: Select language.
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
touch(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.xoxo.po');
|
||||
|
||||
// Check that all predefined languages show up with their native names.
|
||||
$this->visitInstaller();
|
||||
foreach (LanguageManager::getStandardLanguageList() as $langcode => $names) {
|
||||
$this->assertOption('edit-langcode', $langcode);
|
||||
$this->assertRaw('>' . $names[1] . '<');
|
||||
}
|
||||
|
||||
// Check that our custom one shows up with the file name indicated language.
|
||||
$this->assertOption('edit-langcode', 'xoxo');
|
||||
$this->assertRaw('>xoxo<');
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that the installation succeeded.
|
||||
*/
|
||||
public function testInstalled() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests the interactive installer.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Ensures that the user page is available after installation.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
// Confirm that we are logged-in after installation.
|
||||
$this->assertText($this->rootUser->getUsername());
|
||||
|
||||
// Verify that the confirmation message appears.
|
||||
require_once \Drupal::root() . '/core/includes/install.inc';
|
||||
$this->assertRaw(t('Congratulations, you installed @drupal!', [
|
||||
'@drupal' => drupal_install_profile_distribution_name(),
|
||||
]));
|
||||
|
||||
// Ensure that the timezone is correct for sites under test after installing
|
||||
// interactively.
|
||||
$this->assertEqual($this->config('system.date')->get('timezone.default'), 'Australia/Sydney');
|
||||
}
|
||||
|
||||
/**
|
||||
* Installer step: Select language.
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Test that \Drupal\Core\Render\BareHtmlPageRenderer adds assets and
|
||||
// metatags as expected to the first page of the installer.
|
||||
$this->assertRaw('core/themes/seven/css/components/buttons.css');
|
||||
$this->assertRaw('<meta charset="utf-8" />');
|
||||
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Choose language', $this->cssSelect('main h2')[0]);
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Select an installation profile', $this->cssSelect('main h2')[0]);
|
||||
$result = $this->xpath('//span[contains(@class, :class) and contains(text(), :text)]', [':class' => 'visually-hidden', ':text' => 'Select an installation profile']);
|
||||
$this->assertEqual(count($result), 1, "Title/Label not displayed when '#title_display' => 'invisible' attribute is set");
|
||||
|
||||
parent::setUpProfile();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Database configuration', $this->cssSelect('main h2')[0]);
|
||||
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// Assert that the expected title is present.
|
||||
$this->assertEqual('Configure site', $this->cssSelect('main h2')[0]);
|
||||
|
||||
parent::setUpSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
parent::visitInstaller();
|
||||
|
||||
// Assert the title is correct and has the title suffix.
|
||||
$this->assertTitle('Choose language | Drupal');
|
||||
}
|
||||
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
/**
|
||||
* Tests translation files for multiple languages get imported during install.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationMultipleLanguageForeignTest extends InstallerTranslationMultipleLanguageTest {
|
||||
|
||||
/**
|
||||
* Overrides the language code in which to install Drupal.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
parent::setUpLanguage();
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
}
|
||||
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
/**
|
||||
* Tests that keeping English in a foreign language install works.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationMultipleLanguageKeepEnglishTest extends InstallerTranslationMultipleLanguageForeignTest {
|
||||
|
||||
/**
|
||||
* Switch to the multilingual testing profile with English kept.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'testing_multilingual_with_english';
|
||||
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests translation files for multiple languages get imported during install.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationMultipleLanguageTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Switch to the multilingual testing profile.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'testing_multilingual';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place custom local translations in the translations directory.
|
||||
mkdir(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.es.po', $this->getPo('es'));
|
||||
|
||||
parent::setUpLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
|
||||
msgid "Anonymous"
|
||||
msgstr "Anonymous $langcode"
|
||||
|
||||
msgid "Language"
|
||||
msgstr "Language $langcode"
|
||||
|
||||
#: Testing site name configuration during the installer.
|
||||
msgid "Drupal"
|
||||
msgstr "Drupal"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function installParameters() {
|
||||
$params = parent::installParameters();
|
||||
$params['forms']['install_configure_form']['site_name'] = 'SITE_NAME_' . $this->langcode;
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that translations ended up at the expected places.
|
||||
*/
|
||||
public function testTranslationsLoaded() {
|
||||
// Ensure the title is correct.
|
||||
$this->assertEqual('SITE_NAME_' . $this->langcode, \Drupal::config('system.site')->get('name'));
|
||||
|
||||
// Verify German and Spanish were configured.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertText('Spanish');
|
||||
// If the installer was English or we used a profile that keeps English, we
|
||||
// expect that configured also. Otherwise English should not be configured
|
||||
// on the site.
|
||||
if ($this->langcode == 'en' || $this->profile == 'testing_multilingual_with_english') {
|
||||
$this->assertText('English');
|
||||
}
|
||||
else {
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
// Verify the strings from the translation files were imported.
|
||||
$this->verifyImportedStringsTranslated();
|
||||
|
||||
/** @var \Drupal\language\ConfigurableLanguageManager $language_manager */
|
||||
$language_manager = \Drupal::languageManager();
|
||||
|
||||
// If the site was installed in a foreign language (only tested with German
|
||||
// in subclasses), then the active configuration should be updated and no
|
||||
// override should exist in German. Otherwise the German translation should
|
||||
// end up in overrides the same way as Spanish (which is not used as a site
|
||||
// installation language). English should be available based on profile
|
||||
// information and should be possible to add if not yet added, making
|
||||
// English overrides available.
|
||||
|
||||
$config = \Drupal::config('user.settings');
|
||||
$override_de = $language_manager->getLanguageConfigOverride('de', 'user.settings');
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$override_es = $language_manager->getLanguageConfigOverride('es', 'user.settings');
|
||||
|
||||
if ($this->langcode == 'de') {
|
||||
// Active configuration should be in German and no German override should
|
||||
// exist.
|
||||
$this->assertEqual($config->get('anonymous'), 'Anonymous de');
|
||||
$this->assertEqual($config->get('langcode'), 'de');
|
||||
$this->assertTrue($override_de->isNew());
|
||||
|
||||
if ($this->profile == 'testing_multilingual_with_english') {
|
||||
// English is already added in this profile. Should make the override
|
||||
// available.
|
||||
$this->assertEqual($override_en->get('anonymous'), 'Anonymous');
|
||||
}
|
||||
else {
|
||||
// English is not yet available.
|
||||
$this->assertTrue($override_en->isNew());
|
||||
|
||||
// Adding English should make the English override available.
|
||||
$edit = ['predefined_langcode' => 'en'];
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$this->assertEqual($override_en->get('anonymous'), 'Anonymous');
|
||||
}
|
||||
|
||||
// Activate a module, to make sure that config is not overridden by module
|
||||
// installation.
|
||||
$edit = [
|
||||
'modules[views][enable]' => TRUE,
|
||||
'modules[filter][enable]' => TRUE,
|
||||
];
|
||||
$this->drupalPostForm('admin/modules', $edit, t('Install'));
|
||||
|
||||
// Verify the strings from the translation are still as expected.
|
||||
$this->verifyImportedStringsTranslated();
|
||||
}
|
||||
else {
|
||||
// Active configuration should be English.
|
||||
$this->assertEqual($config->get('anonymous'), 'Anonymous');
|
||||
$this->assertEqual($config->get('langcode'), 'en');
|
||||
// There should not be an English override.
|
||||
$this->assertTrue($override_en->isNew());
|
||||
// German should be an override.
|
||||
$this->assertEqual($override_de->get('anonymous'), 'Anonymous de');
|
||||
}
|
||||
|
||||
// Spanish is always an override (never used as installation language).
|
||||
$this->assertEqual($override_es->get('anonymous'), 'Anonymous es');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to verify that the expected strings are translated.
|
||||
*/
|
||||
protected function verifyImportedStringsTranslated() {
|
||||
$test_samples = ['Save and continue', 'Anonymous', 'Language'];
|
||||
$langcodes = ['de', 'es'];
|
||||
|
||||
foreach ($test_samples as $sample) {
|
||||
foreach ($langcodes as $langcode) {
|
||||
$edit = [];
|
||||
$edit['langcode'] = $langcode;
|
||||
$edit['translation'] = 'translated';
|
||||
$edit['string'] = $sample;
|
||||
$this->drupalPostForm('admin/config/regional/translate', $edit, t('Filter'));
|
||||
$this->assertText($sample . ' ' . $langcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Installs Drupal in German and checks resulting site.
|
||||
*
|
||||
* @group Installer
|
||||
*
|
||||
* @see \Drupal\system\Tests\Installer\InstallerTranslationTest
|
||||
*/
|
||||
class InstallerTranslationQueryTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Overrides the language code in which to install Drupal.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function visitInstaller() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
|
||||
// The unrouted URL assembler does not exist at this point, so we build the
|
||||
// URL ourselves.
|
||||
$this->drupalGet($GLOBALS['base_url'] . '/core/install.php' . '?langcode=' . $this->langcode);
|
||||
|
||||
// The language should have been automatically detected, all following
|
||||
// screens should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual((string) current($elements), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = (string) current($this->xpath('/html/@dir'));
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// The language was was preset by passing a query parameter in the URL, so
|
||||
// no explicit language selection is necessary.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the expected behaviors of the installation result.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* Installs Drupal in German and checks resulting site.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class InstallerTranslationTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* Overrides the language code in which to install Drupal.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode = 'de';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpLanguage() {
|
||||
// Place a custom local translation in the translations directory.
|
||||
mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
|
||||
file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', $this->getPo('de'));
|
||||
|
||||
parent::setUpLanguage();
|
||||
|
||||
// After selecting a different language than English, all following screens
|
||||
// should be translated already.
|
||||
$elements = $this->xpath('//input[@type="submit"]/@value');
|
||||
$this->assertEqual((string) current($elements), 'Save and continue de');
|
||||
$this->translations['Save and continue'] = 'Save and continue de';
|
||||
|
||||
// Check the language direction.
|
||||
$direction = (string) current($this->xpath('/html/@dir'));
|
||||
$this->assertEqual($direction, 'ltr');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSettings() {
|
||||
// We are creating a table here to force an error in the installer because
|
||||
// it will try and create the drupal_install_test table as this is part of
|
||||
// the standard database tests performed by the installer in
|
||||
// Drupal\Core\Database\Install\Tasks.
|
||||
Database::getConnection('default')->query('CREATE TABLE {drupal_install_test} (id int NULL)');
|
||||
parent::setUpSettings();
|
||||
|
||||
// Ensure that the error message translation is working.
|
||||
$this->assertRaw('Beheben Sie alle Probleme unten, um die Installation fortzusetzen. Informationen zur Konfiguration der Datenbankserver finden Sie in der <a href="https://www.drupal.org/getting-started/install">Installationshandbuch</a>, oder kontaktieren Sie Ihren Hosting-Anbieter.');
|
||||
$this->assertRaw('<strong>CREATE</strong> ein Test-Tabelle auf Ihrem Datenbankserver mit dem Befehl <em class="placeholder">CREATE TABLE {drupal_install_test} (id int NULL)</em> fehlgeschlagen.');
|
||||
|
||||
// Now do it successfully.
|
||||
Database::getConnection('default')->query('DROP TABLE {drupal_install_test}');
|
||||
parent::setUpSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the expected behaviors of the installation result.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
$this->assertUrl('user/1');
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Verify German was configured but not English.
|
||||
$this->drupalGet('admin/config/regional/language');
|
||||
$this->assertText('German');
|
||||
$this->assertNoText('English');
|
||||
|
||||
// The current container still has the english as current language, rebuild.
|
||||
$this->rebuildContainer();
|
||||
/** @var \Drupal\user\Entity\User $account */
|
||||
$account = User::load(0);
|
||||
$this->assertEqual($account->language()->getId(), 'en', 'Anonymous user is English.');
|
||||
$account = User::load(1);
|
||||
$this->assertEqual($account->language()->getId(), 'en', 'Administrator user is English.');
|
||||
$account = $this->drupalCreateUser();
|
||||
$this->assertEqual($account->language()->getId(), 'de', 'New user is German.');
|
||||
|
||||
// Ensure that we can enable basic_auth on a non-english site.
|
||||
$this->drupalPostForm('admin/modules', ['modules[basic_auth][enable]' => TRUE], t('Install'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Assert that the theme CSS was added to the page.
|
||||
$edit = ['preprocess_css' => FALSE];
|
||||
$this->drupalPostForm('admin/config/development/performance', $edit, t('Save configuration'));
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertRaw('classy/css/components/action-links.css');
|
||||
|
||||
// Verify the strings from the translation files were imported.
|
||||
$test_samples = ['Save and continue', 'Anonymous'];
|
||||
foreach ($test_samples as $sample) {
|
||||
$edit = [];
|
||||
$edit['langcode'] = 'de';
|
||||
$edit['translation'] = 'translated';
|
||||
$edit['string'] = $sample;
|
||||
$this->drupalPostForm('admin/config/regional/translate', $edit, t('Filter'));
|
||||
$this->assertText($sample . ' de');
|
||||
}
|
||||
|
||||
/** @var \Drupal\language\ConfigurableLanguageManager $language_manager */
|
||||
$language_manager = \Drupal::languageManager();
|
||||
|
||||
// Installed in German, configuration should be in German. No German or
|
||||
// English overrides should be present.
|
||||
$config = \Drupal::config('user.settings');
|
||||
$override_de = $language_manager->getLanguageConfigOverride('de', 'user.settings');
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$this->assertEqual($config->get('anonymous'), 'Anonymous de');
|
||||
$this->assertEqual($config->get('langcode'), 'de');
|
||||
$this->assertTrue($override_de->isNew());
|
||||
$this->assertTrue($override_en->isNew());
|
||||
|
||||
// Assert that adding English makes the English override available.
|
||||
$edit = ['predefined_langcode' => 'en'];
|
||||
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
$override_en = $language_manager->getLanguageConfigOverride('en', 'user.settings');
|
||||
$this->assertFalse($override_en->isNew());
|
||||
$this->assertEqual($override_en->get('anonymous'), 'Anonymous');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string for the test .po file.
|
||||
*
|
||||
* @param string $langcode
|
||||
* The language code.
|
||||
* @return string
|
||||
* Contents for the test .po file.
|
||||
*/
|
||||
protected function getPo($langcode) {
|
||||
return <<<ENDPO
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
||||
msgid "Save and continue"
|
||||
msgstr "Save and continue $langcode"
|
||||
|
||||
msgid "Anonymous"
|
||||
msgstr "Anonymous $langcode"
|
||||
|
||||
msgid "Resolve all issues below to continue the installation. For help configuring your database server, see the <a href="https://www.drupal.org/getting-started/install">installation handbook</a>, or contact your hosting provider."
|
||||
msgstr "Beheben Sie alle Probleme unten, um die Installation fortzusetzen. Informationen zur Konfiguration der Datenbankserver finden Sie in der <a href="https://www.drupal.org/getting-started/install">Installationshandbuch</a>, oder kontaktieren Sie Ihren Hosting-Anbieter."
|
||||
|
||||
msgid "Failed to <strong>CREATE</strong> a test table on your database server with the command %query. The server reports the following message: %error.<p>Are you sure the configured username has the necessary permissions to create tables in the database?</p>"
|
||||
msgstr "<strong>CREATE</strong> ein Test-Tabelle auf Ihrem Datenbankserver mit dem Befehl %query fehlgeschlagen."
|
||||
ENDPO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\KernelTests\AssertConfigTrait;
|
||||
|
||||
/**
|
||||
* Tests the interactive installer installing the minimal profile.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class MinimalInstallerTest extends ConfigAfterInstallerTestBase {
|
||||
|
||||
use AssertConfigTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'minimal';
|
||||
|
||||
/**
|
||||
* Ensures that the exported minimal configuration is up to date.
|
||||
*/
|
||||
public function testMinimalConfig() {
|
||||
$this->assertInstalledConfig([]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
<?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');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\simpletest\InstallerTestBase;
|
||||
|
||||
/**
|
||||
* Tests distribution profile support.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class SingleVisibleProfileTest extends InstallerTestBase {
|
||||
|
||||
/**
|
||||
* The installation profile to install.
|
||||
*
|
||||
* Not needed when only one is visible.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = NULL;
|
||||
|
||||
protected function setUp() {
|
||||
$profiles = ['standard', 'demo_umami'];
|
||||
foreach ($profiles as $profile) {
|
||||
$info = [
|
||||
'type' => 'profile',
|
||||
'core' => \Drupal::CORE_COMPATIBILITY,
|
||||
'name' => 'Override ' . $profile,
|
||||
'hidden' => TRUE,
|
||||
];
|
||||
// File API functions are not available yet.
|
||||
$path = $this->siteDirectory . '/profiles/' . $profile;
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/$profile.info.yml", Yaml::encode($info));
|
||||
}
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpProfile() {
|
||||
// This step is skipped, because there is only one visible 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 the minimal profile was installed.
|
||||
$this->assertEqual(drupal_get_profile(), 'minimal');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the site name can be set during a non-interactive installation.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class SiteNameTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* The site name to be used when testing.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $siteName;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function installParameters() {
|
||||
$this->siteName = $this->randomMachineName();
|
||||
$parameters = parent::installParameters();
|
||||
$parameters['forms']['install_configure_form']['site_name'] = $this->siteName;
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the desired site name appears on the page after installation.
|
||||
*/
|
||||
public function testSiteName() {
|
||||
$this->drupalGet('');
|
||||
$this->assertRaw($this->siteName, 'The site name that was set during the installation appears on the front page after installation.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\Installer;
|
||||
|
||||
/**
|
||||
* Tests the interactive installer installing the standard profile.
|
||||
*
|
||||
* @group Installer
|
||||
*/
|
||||
class StandardInstallerTest extends ConfigAfterInstallerTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'standard';
|
||||
|
||||
/**
|
||||
* Ensures that the user page is available after installation.
|
||||
*/
|
||||
public function testInstaller() {
|
||||
// Verify that the Standard install profile's default frontpage appears.
|
||||
$this->assertRaw('No front page content has been created yet.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpSite() {
|
||||
// Test that the correct theme is being used.
|
||||
$this->assertNoRaw('bartik');
|
||||
$this->assertRaw('themes/seven/css/theme/install-page.css');
|
||||
parent::setUpSite();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function curlExec($curl_options, $redirect = FALSE) {
|
||||
// Ensure that we see the classy progress CSS on the batch page.
|
||||
// Batch processing happens as part of HTTP redirects, so we can access the
|
||||
// HTML of the batch page.
|
||||
if (strpos($curl_options[CURLOPT_URL], '&id=1&op=do_nojs') !== FALSE) {
|
||||
$this->assertRaw('themes/classy/css/components/progress.css');
|
||||
}
|
||||
return parent::curlExec($curl_options, $redirect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the exported standard configuration is up to date.
|
||||
*/
|
||||
public function testStandardConfig() {
|
||||
$skipped_config = [];
|
||||
// \Drupal\simpletest\WebTestBase::installParameters() uses
|
||||
// simpletest@example.com as mail address.
|
||||
$skipped_config['contact.form.feedback'][] = '- simpletest@example.com';
|
||||
// \Drupal\filter\Entity\FilterFormat::toArray() drops the roles of filter
|
||||
// formats.
|
||||
$skipped_config['filter.format.basic_html'][] = 'roles:';
|
||||
$skipped_config['filter.format.basic_html'][] = '- authenticated';
|
||||
$skipped_config['filter.format.full_html'][] = 'roles:';
|
||||
$skipped_config['filter.format.full_html'][] = '- administrator';
|
||||
$skipped_config['filter.format.restricted_html'][] = 'roles:';
|
||||
$skipped_config['filter.format.restricted_html'][] = '- anonymous';
|
||||
|
||||
$this->assertInstalledConfig($skipped_config);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,8 +59,9 @@ abstract class ModuleTestBase extends WebTestBase {
|
||||
public function assertModuleTablesExist($module) {
|
||||
$tables = array_keys(drupal_get_module_schema($module));
|
||||
$tables_exist = TRUE;
|
||||
$schema = Database::getConnection()->schema();
|
||||
foreach ($tables as $table) {
|
||||
if (!db_table_exists($table)) {
|
||||
if (!$schema->tableExists($table)) {
|
||||
$tables_exist = FALSE;
|
||||
}
|
||||
}
|
||||
@@ -76,8 +77,9 @@ abstract class ModuleTestBase extends WebTestBase {
|
||||
public function assertModuleTablesDoNotExist($module) {
|
||||
$tables = array_keys(drupal_get_module_schema($module));
|
||||
$tables_exist = FALSE;
|
||||
$schema = Database::getConnection()->schema();
|
||||
foreach ($tables as $table) {
|
||||
if (db_table_exists($table)) {
|
||||
if ($schema->tableExists($table)) {
|
||||
$tables_exist = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,27 +51,26 @@ class UrlAliasFixtures {
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_en',
|
||||
'langcode' => 'en'
|
||||
'langcode' => 'en',
|
||||
],
|
||||
[
|
||||
'source' => '/node/2',
|
||||
'alias' => '/alias_for_node_2_en',
|
||||
'langcode' => 'en'
|
||||
'langcode' => 'en',
|
||||
],
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_fr',
|
||||
'langcode' => 'fr'
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_und',
|
||||
'langcode' => 'und'
|
||||
]
|
||||
'langcode' => 'und',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the table definition for the URL alias fixtures.
|
||||
*
|
||||
|
||||
@@ -57,7 +57,7 @@ class SessionTest extends WebTestBase {
|
||||
// session_test_user_login() which breaks a normal assertion.
|
||||
$edit = [
|
||||
'name' => $user->getUsername(),
|
||||
'pass' => $user->pass_raw
|
||||
'pass' => $user->pass_raw,
|
||||
];
|
||||
$this->drupalPostForm('user/login', $edit, t('Log in'));
|
||||
$this->drupalGet('user');
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\system\Tests\System;
|
||||
|
||||
@trigger_error('\Drupal\system\Tests\System\SystemConfigFormTestBase is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use \Drupal\KernelTests\ConfigFormTestBase instead.', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
@@ -10,12 +12,17 @@ use Drupal\simpletest\WebTestBase;
|
||||
*
|
||||
* @see UserAdminSettingsFormTest
|
||||
* For a full working implementation.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Use
|
||||
* \Drupal\KernelTests\ConfigFormTestBase instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2941907
|
||||
*/
|
||||
abstract class SystemConfigFormTestBase extends WebTestBase {
|
||||
/**
|
||||
* Form ID to use for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Form\FormInterface.
|
||||
* @var \Drupal\Core\Form\FormInterface
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\system\Tests\System;
|
||||
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Tests kernel panic when things are really messed up.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class UncaughtExceptionTest extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Exceptions thrown by site under test that contain this text are ignored.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $expectedExceptionMessage;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['error_service_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$settings_filename = $this->siteDirectory . '/settings.php';
|
||||
chmod($settings_filename, 0777);
|
||||
$settings_php = file_get_contents($settings_filename);
|
||||
$settings_php .= "\ninclude_once 'core/modules/system/src/Tests/Bootstrap/ErrorContainer.php';\n";
|
||||
$settings_php .= "\ninclude_once 'core/modules/system/src/Tests/Bootstrap/ExceptionContainer.php';\n";
|
||||
file_put_contents($settings_filename, $settings_php);
|
||||
|
||||
$settings = [];
|
||||
$settings['config']['system.logging']['error_level'] = (object) [
|
||||
'value' => ERROR_REPORTING_DISPLAY_VERBOSE,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uncaught exception handling when system is in a bad state.
|
||||
*/
|
||||
public function testUncaughtException() {
|
||||
$this->expectedExceptionMessage = 'Oh oh, bananas in the instruments.';
|
||||
\Drupal::state()->set('error_service_test.break_bare_html_renderer', TRUE);
|
||||
|
||||
$this->config('system.logging')
|
||||
->set('error_level', ERROR_REPORTING_HIDE)
|
||||
->save();
|
||||
$settings = [];
|
||||
$settings['config']['system.logging']['error_level'] = (object) [
|
||||
'value' => ERROR_REPORTING_HIDE,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertNoText($this->expectedExceptionMessage);
|
||||
|
||||
$this->config('system.logging')
|
||||
->set('error_level', ERROR_REPORTING_DISPLAY_ALL)
|
||||
->save();
|
||||
$settings = [];
|
||||
$settings['config']['system.logging']['error_level'] = (object) [
|
||||
'value' => ERROR_REPORTING_DISPLAY_ALL,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertText($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests uncaught exception handling with custom exception handler.
|
||||
*/
|
||||
public function testUncaughtExceptionCustomExceptionHandler() {
|
||||
$settings_filename = $this->siteDirectory . '/settings.php';
|
||||
chmod($settings_filename, 0777);
|
||||
$settings_php = file_get_contents($settings_filename);
|
||||
$settings_php .= "\n";
|
||||
$settings_php .= "set_exception_handler(function() {\n";
|
||||
$settings_php .= " header('HTTP/1.1 418 I\'m a teapot');\n";
|
||||
$settings_php .= " print('Oh oh, flying teapots');\n";
|
||||
$settings_php .= "});\n";
|
||||
file_put_contents($settings_filename, $settings_php);
|
||||
|
||||
\Drupal::state()->set('error_service_test.break_bare_html_renderer', TRUE);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(418);
|
||||
$this->assertNoText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertNoText('Oh oh, bananas in the instruments');
|
||||
$this->assertText('Oh oh, flying teapots');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a missing dependency on a service.
|
||||
*/
|
||||
public function testMissingDependency() {
|
||||
if (version_compare(PHP_VERSION, '7.1') < 0) {
|
||||
$this->expectedExceptionMessage = 'Argument 1 passed to Drupal\error_service_test\LonelyMonkeyClass::__construct() must be an instance of Drupal\Core\Database\Connection, non';
|
||||
}
|
||||
else {
|
||||
$this->expectedExceptionMessage = 'Too few arguments to function Drupal\error_service_test\LonelyMonkeyClass::__construct(), 0 passed';
|
||||
}
|
||||
$this->drupalGet('broken-service-class');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->assertRaw('The website encountered an unexpected error.');
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a missing dependency on a service with a custom error handler.
|
||||
*/
|
||||
public function testMissingDependencyCustomErrorHandler() {
|
||||
$settings_filename = $this->siteDirectory . '/settings.php';
|
||||
chmod($settings_filename, 0777);
|
||||
$settings_php = file_get_contents($settings_filename);
|
||||
$settings_php .= "\n";
|
||||
$settings_php .= "set_error_handler(function() {\n";
|
||||
$settings_php .= " header('HTTP/1.1 418 I\'m a teapot');\n";
|
||||
$settings_php .= " print('Oh oh, flying teapots');\n";
|
||||
$settings_php .= " exit();\n";
|
||||
$settings_php .= "});\n";
|
||||
$settings_php .= "\$settings['teapots'] = TRUE;\n";
|
||||
file_put_contents($settings_filename, $settings_php);
|
||||
|
||||
$this->drupalGet('broken-service-class');
|
||||
$this->assertResponse(418);
|
||||
$this->assertRaw('Oh oh, flying teapots');
|
||||
|
||||
$message = 'Argument 1 passed to Drupal\error_service_test\LonelyMonkeyClass::__construct() must be an instance of Drupal\Core\Database\Connection, non';
|
||||
|
||||
$this->assertNoRaw('The website encountered an unexpected error.');
|
||||
$this->assertNoRaw($message);
|
||||
|
||||
$found_exception = FALSE;
|
||||
foreach ($this->assertions as &$assertion) {
|
||||
if (strpos($assertion['message'], $message) !== FALSE) {
|
||||
$found_exception = TRUE;
|
||||
$this->deleteAssert($assertion['message_id']);
|
||||
unset($assertion);
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertTrue($found_exception, 'Ensure that the exception of a missing constructor argument was triggered.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a container which has an error.
|
||||
*/
|
||||
public function testErrorContainer() {
|
||||
$settings = [];
|
||||
$settings['settings']['container_base_class'] = (object) [
|
||||
'value' => '\Drupal\system\Tests\Bootstrap\ErrorContainer',
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
\Drupal::service('kernel')->invalidateContainer();
|
||||
|
||||
$this->expectedExceptionMessage = 'Argument 1 passed to Drupal\system\Tests\Bootstrap\ErrorContainer::Drupal\system\Tests\Bootstrap\{closur';
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a container which has an exception really early.
|
||||
*/
|
||||
public function testExceptionContainer() {
|
||||
$settings = [];
|
||||
$settings['settings']['container_base_class'] = (object) [
|
||||
'value' => '\Drupal\system\Tests\Bootstrap\ExceptionContainer',
|
||||
'required' => TRUE,
|
||||
];
|
||||
$this->writeSettings($settings);
|
||||
\Drupal::service('kernel')->invalidateContainer();
|
||||
|
||||
$this->expectedExceptionMessage = 'Thrown exception during Container::get';
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->assertRaw('The website encountered an unexpected error');
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the case when the database connection is gone.
|
||||
*/
|
||||
public function testLostDatabaseConnection() {
|
||||
$incorrect_username = $this->randomMachineName(16);
|
||||
switch ($this->container->get('database')->driver()) {
|
||||
case 'pgsql':
|
||||
case 'mysql':
|
||||
$this->expectedExceptionMessage = $incorrect_username;
|
||||
break;
|
||||
default:
|
||||
// We can not carry out this test.
|
||||
$this->pass('Unable to run \Drupal\system\Tests\System\UncaughtExceptionTest::testLostDatabaseConnection for this database type.');
|
||||
return;
|
||||
}
|
||||
|
||||
// We simulate a broken database connection by rewrite settings.php to no
|
||||
// longer have the proper data.
|
||||
$settings['databases']['default']['default']['username'] = (object) [
|
||||
'value' => $incorrect_username,
|
||||
'required' => TRUE,
|
||||
];
|
||||
$settings['databases']['default']['default']['password'] = (object) [
|
||||
'value' => $this->randomMachineName(16),
|
||||
'required' => TRUE,
|
||||
];
|
||||
|
||||
$this->writeSettings($settings);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertRaw('DatabaseAccessDeniedException');
|
||||
$this->assertErrorLogged($this->expectedExceptionMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests fallback to PHP error log when an exception is thrown while logging.
|
||||
*/
|
||||
public function testLoggerException() {
|
||||
// Ensure the test error log is empty before these tests.
|
||||
$this->assertNoErrorsLogged();
|
||||
|
||||
$this->expectedExceptionMessage = 'Deforestation';
|
||||
\Drupal::state()->set('error_service_test.break_logger', TRUE);
|
||||
|
||||
$this->drupalGet('');
|
||||
$this->assertResponse(500);
|
||||
$this->assertText('The website encountered an unexpected error. Please try again later.');
|
||||
$this->assertRaw($this->expectedExceptionMessage);
|
||||
|
||||
// Find fatal error logged to the simpletest error.log
|
||||
$errors = file(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
|
||||
$this->assertIdentical(count($errors), 8, 'The error + the error that the logging service is broken has been written to the error log.');
|
||||
$this->assertTrue(strpos($errors[0], 'Failed to log error') !== FALSE, 'The error handling logs when an error could not be logged to the logger.');
|
||||
|
||||
$expected_path = \Drupal::root() . '/core/modules/system/tests/modules/error_service_test/src/MonkeysInTheControlRoom.php';
|
||||
$expected_line = 59;
|
||||
$expected_entry = "Failed to log error: Exception: Deforestation in Drupal\\error_service_test\\MonkeysInTheControlRoom->handle() (line ${expected_line} of ${expected_path})";
|
||||
$this->assert(strpos($errors[0], $expected_entry) !== FALSE, 'Original error logged to the PHP error log when an exception is thrown by a logger');
|
||||
|
||||
// The exception is expected. Do not interpret it as a test failure. Not
|
||||
// using File API; a potential error must trigger a PHP warning.
|
||||
unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function error($message = '', $group = 'Other', array $caller = NULL) {
|
||||
if (!empty($this->expectedExceptionMessage) && strpos($message, $this->expectedExceptionMessage) !== FALSE) {
|
||||
// We're expecting this error.
|
||||
return FALSE;
|
||||
}
|
||||
return parent::error($message, $group, $caller);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@ function hook_system_themes_page_alter(&$theme_groups) {
|
||||
$theme->operations[] = [
|
||||
'title' => t('Foo'),
|
||||
'url' => Url::fromRoute('system.themes_page'),
|
||||
'query' => ['theme' => $theme->getName()]
|
||||
'query' => ['theme' => $theme->getName()],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +51,10 @@ function system_requirements($phase) {
|
||||
'value' => t('%profile_name (%profile-%version)', [
|
||||
'%profile_name' => $info['name'],
|
||||
'%profile' => $profile,
|
||||
'%version' => $info['version']
|
||||
'%version' => $info['version'],
|
||||
]),
|
||||
'severity' => REQUIREMENT_INFO,
|
||||
'weight' => -9
|
||||
'weight' => -9,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -77,14 +77,15 @@ function system_requirements($phase) {
|
||||
}
|
||||
|
||||
// Web server information.
|
||||
$software = \Drupal::request()->server->get('SERVER_SOFTWARE');
|
||||
$request_object = \Drupal::request();
|
||||
$software = $request_object->server->get('SERVER_SOFTWARE');
|
||||
$requirements['webserver'] = [
|
||||
'title' => t('Web server'),
|
||||
'value' => $software,
|
||||
];
|
||||
|
||||
// Tests clean URL support.
|
||||
if ($phase == 'install' && $install_state['interactive'] && !isset($_GET['rewrite']) && strpos($software, 'Apache') !== FALSE) {
|
||||
if ($phase == 'install' && $install_state['interactive'] && !$request_object->query->has('rewrite') && strpos($software, 'Apache') !== FALSE) {
|
||||
// If the Apache rewrite module is not enabled, Apache version must be >=
|
||||
// 2.2.16 because of the FallbackResource directive in the root .htaccess
|
||||
// file. Since the Apache version reported by the server is dependent on the
|
||||
@@ -435,12 +436,13 @@ function system_requirements($phase) {
|
||||
// directory. This allows additional files in the site directory to be
|
||||
// updated when they are managed in a version control system.
|
||||
if (Settings::get('skip_permissions_hardening')) {
|
||||
$conf_errors[] = t('Protection disabled');
|
||||
$error_value = t('Protection disabled');
|
||||
// If permissions hardening is disabled, then only show a warning for a
|
||||
// writable file, as a reminder, rather than an error.
|
||||
$file_protection_severity = REQUIREMENT_WARNING;
|
||||
}
|
||||
else {
|
||||
$error_value = t('Not protected');
|
||||
// In normal operation, writable files or directories are an error.
|
||||
$file_protection_severity = REQUIREMENT_ERROR;
|
||||
if (!drupal_verify_install_file($site_path, FILE_NOT_WRITABLE, 'dir')) {
|
||||
@@ -449,7 +451,7 @@ function system_requirements($phase) {
|
||||
}
|
||||
foreach (['settings.php', 'settings.local.php', 'services.yml'] as $conf_file) {
|
||||
$full_path = $site_path . '/' . $conf_file;
|
||||
if (file_exists($full_path) && (Settings::get('skip_permissions_hardening') || !drupal_verify_install_file($full_path, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE))) {
|
||||
if (file_exists($full_path) && !drupal_verify_install_file($full_path, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE, 'file', !Settings::get('skip_permissions_hardening'))) {
|
||||
$conf_errors[] = t("The file %file is not protected from modifications and poses a security risk. You must change the file's permissions to be non-writable.", ['%file' => $full_path]);
|
||||
}
|
||||
}
|
||||
@@ -471,7 +473,7 @@ function system_requirements($phase) {
|
||||
];
|
||||
}
|
||||
$requirements['configuration_files'] = [
|
||||
'value' => t('Not protected'),
|
||||
'value' => $error_value,
|
||||
'severity' => $file_protection_severity,
|
||||
'description' => $description,
|
||||
];
|
||||
@@ -1000,6 +1002,34 @@ function system_requirements($phase) {
|
||||
];
|
||||
}
|
||||
|
||||
// During installs from configuration don't support install profiles that
|
||||
// implement hook_install.
|
||||
if ($phase == 'install' && !empty($install_state['config_install_path'])) {
|
||||
$install_hook = $install_state['parameters']['profile'] . '_install';
|
||||
if (function_exists($install_hook)) {
|
||||
$requirements['config_install'] = [
|
||||
'title' => t('Configuration install'),
|
||||
'value' => $install_state['parameters']['profile'],
|
||||
'description' => t('The selected profile has a hook_install() implementation and therefore can not be installed from configuration.'),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($phase === 'runtime') {
|
||||
$settings = Settings::getAll();
|
||||
if (array_key_exists('install_profile', $settings)) {
|
||||
// The following message is only informational because not all site owners
|
||||
// have access to edit their settings.php as it may be controlled by their
|
||||
// hosting provider.
|
||||
$requirements['install_profile_in_settings'] = [
|
||||
'title' => t('Install profile in settings'),
|
||||
'value' => t("Drupal 8 no longer uses the \$settings['install_profile'] value in settings.php and it can be removed."),
|
||||
'severity' => REQUIREMENT_INFO,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
@@ -1836,6 +1866,10 @@ function system_update_8200(&$sandbox) {
|
||||
*/
|
||||
function system_update_8201() {
|
||||
// Empty update to cause a cache rebuild.
|
||||
|
||||
// Use hook_post_update_NAME() instead to clear the cache.
|
||||
// The use of hook_update_N() to clear the cache has been deprecated
|
||||
// see https://www.drupal.org/node/2960601 for more details.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1843,6 +1877,10 @@ function system_update_8201() {
|
||||
*/
|
||||
function system_update_8202() {
|
||||
// Empty update to cause a cache rebuild.
|
||||
|
||||
// Use hook_post_update_NAME() instead to clear the cache.The use
|
||||
// of hook_update_N to clear the cache has been deprecated see
|
||||
// https://www.drupal.org/node/2960601 for more details.
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,10 +9,10 @@ use Drupal\Component\Render\PlainTextOutput;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\Asset\AttachedAssetsInterface;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Extension\Exception\UnknownExtensionException;
|
||||
use Drupal\Core\Queue\QueueGarbageCollectionInterface;
|
||||
use Drupal\Core\Database\Query\AlterableInterface;
|
||||
use Drupal\Core\Extension\Extension;
|
||||
use Drupal\Core\Extension\ExtensionDiscovery;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueDatabaseExpirableFactory;
|
||||
use Drupal\Core\PageCache\RequestPolicyInterface;
|
||||
@@ -767,10 +767,10 @@ function system_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
|
||||
}
|
||||
// Provide the page with information about the individual asset libraries
|
||||
// used, information not otherwise available when aggregation is enabled.
|
||||
$minimal_libraries = $library_dependency_resolver->getMinimalRepresentativeSubset(array_merge(
|
||||
$minimal_libraries = $library_dependency_resolver->getMinimalRepresentativeSubset(array_unique(array_merge(
|
||||
$assets->getLibraries(),
|
||||
$assets->getAlreadyLoadedLibraries()
|
||||
));
|
||||
)));
|
||||
sort($minimal_libraries);
|
||||
$settings['ajaxPageState']['libraries'] = implode(',', $minimal_libraries);
|
||||
}
|
||||
@@ -835,7 +835,13 @@ function system_user_login(UserInterface $account) {
|
||||
$config = \Drupal::config('system.date');
|
||||
// If the user has a NULL time zone, notify them to set a time zone.
|
||||
if (!$account->getTimezone() && $config->get('timezone.user.configurable') && $config->get('timezone.user.warn')) {
|
||||
drupal_set_message(t('Configure your <a href=":user-edit">account time zone setting</a>.', [':user-edit' => $account->url('edit-form', ['query' => \Drupal::destination()->getAsArray(), 'fragment' => 'edit-timezone'])]));
|
||||
\Drupal::messenger()
|
||||
->addStatus(t('Configure your <a href=":user-edit">account time zone setting</a>.', [
|
||||
':user-edit' => $account->url('edit-form', [
|
||||
'query' => \Drupal::destination()->getAsArray(),
|
||||
'fragment' => 'edit-timezone',
|
||||
]),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,7 +919,7 @@ function system_check_directory($form_element, FormStateInterface $form_state) {
|
||||
|
||||
$logger = \Drupal::logger('file system');
|
||||
if (!is_dir($directory) && !drupal_mkdir($directory, NULL, TRUE)) {
|
||||
// If the directory does not exists and cannot be created.
|
||||
// If the directory does not exist and cannot be created.
|
||||
$form_state->setErrorByName($form_element['#parents'][0], t('The directory %directory does not exist and could not be created.', ['%directory' => $directory]));
|
||||
$logger->error('The directory %directory does not exist and could not be created.', ['%directory' => $directory]);
|
||||
}
|
||||
@@ -961,27 +967,22 @@ function system_check_directory($form_element, FormStateInterface $form_state) {
|
||||
*/
|
||||
function system_get_info($type, $name = NULL) {
|
||||
if ($type == 'module') {
|
||||
$info = &drupal_static(__FUNCTION__);
|
||||
if (!isset($info)) {
|
||||
if ($cache = \Drupal::cache()->get('system.module.info')) {
|
||||
$info = $cache->data;
|
||||
/** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
|
||||
$module_list = \Drupal::service('extension.list.module');
|
||||
if (isset($name)) {
|
||||
try {
|
||||
return $module_list->getExtensionInfo($name);
|
||||
}
|
||||
else {
|
||||
$data = system_rebuild_module_data();
|
||||
foreach (\Drupal::moduleHandler()->getModuleList() as $module => $filename) {
|
||||
if (isset($data[$module])) {
|
||||
$info[$module] = $data[$module]->info;
|
||||
}
|
||||
}
|
||||
// Store the module information in cache. This cache is cleared by
|
||||
// calling system_rebuild_module_data(), for example, when listing
|
||||
// modules, (un)installing modules, importing configuration, updating
|
||||
// the site and when flushing all the caches.
|
||||
\Drupal::cache()->set('system.module.info', $info);
|
||||
catch (UnknownExtensionException $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $module_list->getAllInstalledInfo();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// @todo move into ThemeExtensionList https://www.drupal.org/node/2659940
|
||||
$info = [];
|
||||
$list = system_list($type);
|
||||
foreach ($list as $shortname => $item) {
|
||||
@@ -989,96 +990,11 @@ function system_get_info($type, $name = NULL) {
|
||||
$info[$shortname] = $item->info;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($name)) {
|
||||
return isset($info[$name]) ? $info[$name] : [];
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to scan and collect module .info.yml data.
|
||||
*
|
||||
* @return \Drupal\Core\Extension\Extension[]
|
||||
* An associative array of module information.
|
||||
*/
|
||||
function _system_rebuild_module_data() {
|
||||
$listing = new ExtensionDiscovery(\Drupal::root());
|
||||
|
||||
// Find installation profiles. This needs to happen before performing a
|
||||
// module scan as the module scan requires knowing what the active profile is.
|
||||
// @todo Remove as part of https://www.drupal.org/node/2186491.
|
||||
$profiles = $listing->scan('profile');
|
||||
$profile = drupal_get_profile();
|
||||
if ($profile && isset($profiles[$profile])) {
|
||||
// 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, $profiles[$profile]->getPathname());
|
||||
}
|
||||
|
||||
// Find modules.
|
||||
$modules = $listing->scan('module');
|
||||
// Include the installation profile in modules that are loaded.
|
||||
if ($profile) {
|
||||
$modules[$profile] = $profiles[$profile];
|
||||
// Installation profile hooks are always executed last.
|
||||
$modules[$profile]->weight = 1000;
|
||||
}
|
||||
|
||||
// Set defaults for module info.
|
||||
$defaults = [
|
||||
'dependencies' => [],
|
||||
'description' => '',
|
||||
'package' => 'Other',
|
||||
'version' => NULL,
|
||||
'php' => DRUPAL_MINIMUM_PHP,
|
||||
];
|
||||
|
||||
// Read info files for each module.
|
||||
foreach ($modules as $key => $module) {
|
||||
// Look for the info file.
|
||||
$module->info = \Drupal::service('info_parser')->parse($module->getPathname());
|
||||
|
||||
// Add the info file modification time, so it becomes available for
|
||||
// contributed modules to use for ordering module lists.
|
||||
$module->info['mtime'] = $module->getMTime();
|
||||
|
||||
// Merge in defaults and save.
|
||||
$modules[$key]->info = $module->info + $defaults;
|
||||
|
||||
// Installation profiles are hidden by default, unless explicitly specified
|
||||
// otherwise in the .info.yml file.
|
||||
if ($key == $profile && !isset($modules[$key]->info['hidden'])) {
|
||||
$modules[$key]->info['hidden'] = TRUE;
|
||||
if (isset($name)) {
|
||||
return isset($info[$name]) ? $info[$name] : [];
|
||||
}
|
||||
|
||||
// Invoke hook_system_info_alter() to give installed modules a chance to
|
||||
// modify the data in the .info.yml files if necessary.
|
||||
// @todo Remove $type argument, obsolete with $module->getType().
|
||||
$type = 'module';
|
||||
\Drupal::moduleHandler()->alter('system_info', $modules[$key]->info, $modules[$key], $type);
|
||||
return $info;
|
||||
}
|
||||
|
||||
// It is possible that a module was marked as required by
|
||||
// hook_system_info_alter() and modules that it depends on are not required.
|
||||
foreach ($modules as $module) {
|
||||
_system_rebuild_module_data_ensure_required($module, $modules);
|
||||
}
|
||||
|
||||
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.
|
||||
// @see install_profile_info()
|
||||
// @see drupal_install_profile_distribution_name()
|
||||
if (!isset($modules[$profile]->info['distribution']['name'])) {
|
||||
$modules[$profile]->info['distribution']['name'] = 'Drupal';
|
||||
}
|
||||
}
|
||||
|
||||
return $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1088,8 +1004,14 @@ function _system_rebuild_module_data() {
|
||||
* The module info.
|
||||
* @param \Drupal\Core\Extension\Extension[] $modules
|
||||
* The array of all module info.
|
||||
*
|
||||
* @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. This
|
||||
* function is no longer used in Drupal core.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2709919
|
||||
*/
|
||||
function _system_rebuild_module_data_ensure_required($module, &$modules) {
|
||||
@trigger_error("_system_rebuild_module_data_ensure_required() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. This function is no longer used in Drupal core. See https://www.drupal.org/node/2709919", E_USER_DEPRECATED);
|
||||
if (!empty($module->info['required'])) {
|
||||
foreach ($module->info['dependencies'] as $dependency) {
|
||||
$dependency_name = ModuleHandler::parseDependency($dependency)['name'];
|
||||
@@ -1103,6 +1025,23 @@ function _system_rebuild_module_data_ensure_required($module, &$modules) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to scan and collect module .info.yml data.
|
||||
*
|
||||
* @return \Drupal\Core\Extension\Extension[]
|
||||
* An associative array of module information.
|
||||
*
|
||||
* @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0.
|
||||
* Use \Drupal::service('extension.list.module')->reset()->getList()
|
||||
* instead. Note: You probably don't need the reset() method.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2709919
|
||||
*/
|
||||
function _system_rebuild_module_data() {
|
||||
@trigger_error("_system_rebuild_module_data() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. Instead, you should use \\Drupal::service('extension.list.module')->reset()->getList(). See https://www.drupal.org/node/2709919", E_USER_DEPRECATED);
|
||||
return \Drupal::service('extension.list.module')->reset()->getList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild, save, and return data about all currently available modules.
|
||||
*
|
||||
@@ -1110,33 +1049,7 @@ function _system_rebuild_module_data_ensure_required($module, &$modules) {
|
||||
* Array of all available modules and their data.
|
||||
*/
|
||||
function system_rebuild_module_data() {
|
||||
$modules_cache = &drupal_static(__FUNCTION__);
|
||||
// Only rebuild once per request. $modules and $modules_cache cannot be
|
||||
// combined into one variable, because the $modules_cache variable is reset by
|
||||
// reference from system_list_reset() during the rebuild.
|
||||
if (!isset($modules_cache)) {
|
||||
$modules = _system_rebuild_module_data();
|
||||
$files = [];
|
||||
ksort($modules);
|
||||
// Add status, weight, and schema version.
|
||||
$installed_modules = \Drupal::config('core.extension')->get('module') ?: [];
|
||||
foreach ($modules as $name => $module) {
|
||||
$module->weight = isset($installed_modules[$name]) ? $installed_modules[$name] : 0;
|
||||
$module->status = (int) isset($installed_modules[$name]);
|
||||
$module->schema_version = SCHEMA_UNINSTALLED;
|
||||
$files[$name] = $module->getPathname();
|
||||
}
|
||||
$modules = \Drupal::moduleHandler()->buildModuleDependencies($modules);
|
||||
$modules_cache = $modules;
|
||||
|
||||
// Store filenames to allow drupal_get_filename() to retrieve them without
|
||||
// having to rebuild or scan the filesystem.
|
||||
\Drupal::state()->set('system.module.files', $files);
|
||||
// Clear the module info cache.
|
||||
\Drupal::cache()->delete('system.module.info');
|
||||
drupal_static_reset('system_get_info');
|
||||
}
|
||||
return $modules_cache;
|
||||
return \Drupal::service('extension.list.module')->reset()->getList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1461,11 +1374,11 @@ function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $repl
|
||||
$local = $managed ? file_save_data($data, $path, $replace) : file_unmanaged_save_data($data, $path, $replace);
|
||||
}
|
||||
catch (RequestException $exception) {
|
||||
drupal_set_message(t('Failed to fetch file due to error "%error"', ['%error' => $exception->getMessage()]), 'error');
|
||||
\Drupal::messenger()->addError(t('Failed to fetch file due to error "%error"', ['%error' => $exception->getMessage()]));
|
||||
return FALSE;
|
||||
}
|
||||
if (!$local) {
|
||||
drupal_set_message(t('@remote could not be saved to @path.', ['@remote' => $url, '@path' => $path]), 'error');
|
||||
\Drupal::messenger()->addError(t('@remote could not be saved to @path.', ['@remote' => $url, '@path' => $path]));
|
||||
}
|
||||
|
||||
return $local;
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
* Post update functions for System.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityUpdater;
|
||||
use Drupal\Core\Entity\Display\EntityDisplayInterface;
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Entity\Entity\EntityViewDisplay;
|
||||
|
||||
@@ -49,7 +51,6 @@ function system_post_update_add_region_to_entity_displays() {
|
||||
array_map($entity_save, EntityFormDisplay::loadMultiple());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Force caches using hashes to be cleared (Twig, render cache, etc.).
|
||||
*/
|
||||
@@ -111,3 +112,60 @@ function system_post_update_change_action_plugins() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change plugin IDs of delete actions.
|
||||
*/
|
||||
function system_post_update_change_delete_action_plugins() {
|
||||
$old_new_action_id_map = [
|
||||
'comment_delete_action' => 'entity:delete_action:comment',
|
||||
'node_delete_action' => 'entity:delete_action:node',
|
||||
];
|
||||
|
||||
/** @var \Drupal\system\Entity\Action[] $actions */
|
||||
$actions = \Drupal::entityTypeManager()->getStorage('action')->loadMultiple();
|
||||
foreach ($actions as $action) {
|
||||
if (isset($old_new_action_id_map[$action->getPlugin()->getPluginId()])) {
|
||||
$action->setPlugin($old_new_action_id_map[$action->getPlugin()->getPluginId()]);
|
||||
$action->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force cache clear for language item callback.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2851736
|
||||
*/
|
||||
function system_post_update_language_item_callback() {
|
||||
// Empty post-update hook.
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all entity displays that contain extra fields.
|
||||
*/
|
||||
function system_post_update_extra_fields(&$sandbox = NULL) {
|
||||
$config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
|
||||
$entity_field_manager = \Drupal::service('entity_field.manager');
|
||||
|
||||
$callback = function (EntityDisplayInterface $display) use ($entity_field_manager) {
|
||||
$display_context = $display instanceof EntityViewDisplayInterface ? 'display' : 'form';
|
||||
$extra_fields = $entity_field_manager->getExtraFields($display->getTargetEntityTypeId(), $display->getTargetBundle());
|
||||
|
||||
// If any extra fields are used as a component, resave the display with the
|
||||
// updated component information.
|
||||
$needs_save = FALSE;
|
||||
if (!empty($extra_fields[$display_context])) {
|
||||
foreach ($extra_fields[$display_context] as $name => $extra_field) {
|
||||
if ($component = $display->getComponent($name)) {
|
||||
$display->setComponent($name, $component);
|
||||
$needs_save = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $needs_save;
|
||||
};
|
||||
|
||||
$config_entity_updater->update($sandbox, 'entity_form_display', $callback);
|
||||
$config_entity_updater->update($sandbox, 'entity_view_display', $callback);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@
|
||||
* @ingroup themeable
|
||||
*/
|
||||
#}
|
||||
{%
|
||||
set title_classes = [
|
||||
label_display == 'visually_hidden' ? 'visually-hidden',
|
||||
]
|
||||
%}
|
||||
|
||||
{% if label_hidden %}
|
||||
{% if multiple %}
|
||||
@@ -53,7 +58,7 @@
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div{{ attributes }}>
|
||||
<div{{ title_attributes }}>{{ label }}</div>
|
||||
<div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
|
||||
{% if multiple %}
|
||||
<div>
|
||||
{% endif %}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
* Available variables:
|
||||
* - message_list: List of messages to be displayed, grouped by type.
|
||||
* - status_headings: List of all status types.
|
||||
* - display: (optional) May have a value of 'status' or 'error' when only
|
||||
* displaying messages of that specific type.
|
||||
* - attributes: HTML attributes for the element, including:
|
||||
* - class: HTML classes.
|
||||
*
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ $existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.testfor2354889', 'block.block.secondtestfor2354889', 'block.block.thirdtestfor2354889']))
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.testfor2354889', 'block.block.secondtestfor2354889', 'block.block.thirdtestfor2354889'])),
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:bartik')
|
||||
|
||||
Binary file not shown.
Vendored
+2
-2
@@ -40,7 +40,7 @@ $existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.seven_local_actions']))
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.seven_local_actions'])),
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:seven')
|
||||
@@ -55,7 +55,7 @@ $extensions = $connection->select('config')
|
||||
$extensions = unserialize($extensions);
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_theme' => 0]]))
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_theme' => 0]])),
|
||||
])
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@ $existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.bartik_page_title']))
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.bartik_page_title'])),
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:bartik')
|
||||
@@ -55,7 +55,7 @@ $extensions = $connection->select('config')
|
||||
$extensions = unserialize($extensions);
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_theme' => 0]]))
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_theme' => 0]])),
|
||||
])
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
|
||||
Vendored
+1
-1
@@ -40,7 +40,7 @@ $existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.seven_secondary_local_tasks']))
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.seven_secondary_local_tasks'])),
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:seven')
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@ $existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.bartik_branding']))
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.bartik_branding'])),
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:bartik')
|
||||
@@ -55,7 +55,7 @@ $extensions = $connection->select('config')
|
||||
$extensions = unserialize($extensions);
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_theme' => 0]]))
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_theme' => 0]])),
|
||||
])
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ $extensions = $connection->select('config')
|
||||
$extensions = unserialize($extensions);
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_stable' => 0]]))
|
||||
'data' => serialize(array_merge_recursive($extensions, ['theme' => ['test_stable' => 0]])),
|
||||
])
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ $existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.testfor2513534', 'block.block.secondtestfor2513534']))
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.testfor2513534', 'block.block.secondtestfor2513534'])),
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:bartik')
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains database additions to drupal-8.bare.standard.php.gz for testing the
|
||||
* upgrade path of https://www.drupal.org/node/2455125.
|
||||
*/
|
||||
|
||||
use Drupal\Component\Uuid\Php;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
$view_file = __DIR__ . '/drupal-8.views-taxonomy-parent-2543726.yml';
|
||||
$view_config = Yaml::decode(file_get_contents($view_file));
|
||||
|
||||
$connection->insert('config')
|
||||
->fields(['collection', 'name', 'data'])
|
||||
->values([
|
||||
'collection' => '',
|
||||
'name' => "views.view.test_taxonomy_parent",
|
||||
'data' => serialize($view_config),
|
||||
])
|
||||
->execute();
|
||||
|
||||
$uuid = new Php();
|
||||
|
||||
// The root tid.
|
||||
$tids = [0];
|
||||
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$name = $this->randomString();
|
||||
|
||||
$tid = $connection->insert('taxonomy_term_data')
|
||||
->fields(['vid', 'uuid', 'langcode'])
|
||||
->values(['vid' => 'tags', 'uuid' => $uuid->generate(), 'langcode' => 'en'])
|
||||
->execute();
|
||||
|
||||
$connection->insert('taxonomy_term_field_data')
|
||||
->fields(['tid', 'vid', 'langcode', 'name', 'weight', 'changed', 'default_langcode'])
|
||||
->values(['tid' => $tid, 'vid' => 'tags', 'langcode' => 'en', 'name' => $name, 'weight' => 0, 'changed' => REQUEST_TIME, 'default_langcode' => 1])
|
||||
->execute();
|
||||
|
||||
$tids[] = $tid;
|
||||
}
|
||||
|
||||
$hierarchy = [
|
||||
// Term with tid 1 has terms with tids 2 and 3 as parents.
|
||||
1 => [2, 3],
|
||||
2 => [3, 0],
|
||||
3 => [0],
|
||||
];
|
||||
|
||||
$query = $connection->insert('taxonomy_term_hierarchy')->fields(['tid', 'parent']);
|
||||
|
||||
foreach ($hierarchy as $tid => $parents) {
|
||||
foreach ($parents as $parent) {
|
||||
$query->values(['tid' => $tids[$tid], 'parent' => $tids[$parent]]);
|
||||
}
|
||||
}
|
||||
|
||||
$query->execute();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user