updated core to 8.6.1 via composer

This commit is contained in:
2018-09-12 13:58:26 +02:00
parent a9a219f2ed
commit ea56b9fba3
4443 changed files with 112098 additions and 40708 deletions
+1 -1
View File
@@ -150,7 +150,7 @@ function hook_block_view_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\B
*/
function hook_block_build_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
// Add the 'user' cache context to some blocks.
if ($some_condition) {
if ($block->label() === 'some condition') {
$build['#cache']['contexts'][] = 'user';
}
}
+1 -1
View File
@@ -73,7 +73,7 @@ function block_update_8001() {
// their own updates.
$update_backup[$block->get('id')] = [
'missing_context_ids' => $backup_values,
'status' => $block->get('status')
'status' => $block->get('status'),
];
}
}
+5 -1
View File
@@ -145,7 +145,11 @@ function block_rebuild() {
// Disable blocks in invalid regions.
if (!isset($regions[$block->getRegion()])) {
if ($block->status()) {
drupal_set_message(t('The block %info was assigned to the invalid region %region and has been disabled.', ['%info' => $block_id, '%region' => $block->getRegion()]), 'warning');
\Drupal::messenger()
->addWarning(t('The block %info was assigned to the invalid region %region and has been disabled.', [
'%info' => $block_id,
'%region' => $block->getRegion(),
]));
}
$block
->setRegion(system_default_region($theme))
+1 -1
View File
@@ -60,7 +60,7 @@ function block_post_update_disable_blocks_with_missing_contexts() {
foreach ($blocks as $disabled_block_id => $disabled_block) {
$message .= '<li>' . t('@label (Visibility: @plugin_ids)', [
'@label' => $disabled_block->get('settings')['label'],
'@plugin_ids' => implode(', ', array_intersect_key($condition_plugin_id_label_map, array_flip(array_keys($block_update_8001[$disabled_block_id]['missing_context_ids']))))
'@plugin_ids' => implode(', ', array_intersect_key($condition_plugin_id_label_map, array_flip(array_keys($block_update_8001[$disabled_block_id]['missing_context_ids'])))),
]) . '</li>';
}
$message .= '</ul>';
+33 -16
View File
@@ -3,7 +3,7 @@
* Block admin behaviors.
*/
(function ($, Drupal, debounce) {
(function($, Drupal, debounce) {
/**
* Filters the block list by a text input search string.
*
@@ -33,7 +33,9 @@
* The jQuery event for the keyup event that triggered the filter.
*/
function filterBlockList(e) {
const query = $(e.target).val().toLowerCase();
const query = $(e.target)
.val()
.toLowerCase();
/**
* Shows or hides the block entry based on the query.
@@ -46,7 +48,11 @@
function toggleBlockEntry(index, label) {
const $label = $(label);
const $row = $label.parent().parent();
const textMatch = $label.text().toLowerCase().indexOf(query) !== -1;
const textMatch =
$label
.text()
.toLowerCase()
.indexOf(query) !== -1;
$row.toggle(textMatch);
}
@@ -60,10 +66,12 @@
'@count blocks are available in the modified list.',
),
);
}
else {
$filterRows.each(function (index) {
$(this).parent().parent().show();
} else {
$filterRows.each(function(index) {
$(this)
.parent()
.parent()
.show();
});
}
}
@@ -86,15 +94,24 @@
Drupal.behaviors.blockHighlightPlacement = {
attach(context, settings) {
if (settings.blockPlacement) {
$(context).find('[data-drupal-selector="edit-blocks"]').once('block-highlight').each(function () {
const $container = $(this);
// Just scrolling the document.body will not work in Firefox. The html
// element is needed as well.
$('html, body').animate({
scrollTop: ($('.js-block-placed').offset().top - $container.offset().top) + $container.scrollTop(),
}, 500);
});
$(context)
.find('[data-drupal-selector="edit-blocks"]')
.once('block-highlight')
.each(function() {
const $container = $(this);
// Just scrolling the document.body will not work in Firefox. The html
// element is needed as well.
$('html, body').animate(
{
scrollTop:
$('.js-block-placed').offset().top -
$container.offset().top +
$container.scrollTop(),
},
500,
);
});
}
},
};
}(jQuery, Drupal, Drupal.debounce));
})(jQuery, Drupal, Drupal.debounce);
+64 -24
View File
@@ -3,7 +3,7 @@
* Block behaviors.
*/
(function ($, window, Drupal) {
(function($, window, Drupal) {
/**
* Provide the summary information for the block settings vertical tabs.
*
@@ -32,7 +32,9 @@
*/
function checkboxesSummary(context) {
const vals = [];
const $checkboxes = $(context).find('input[type="checkbox"]:checked + label');
const $checkboxes = $(context).find(
'input[type="checkbox"]:checked + label',
);
const il = $checkboxes.length;
for (let i = 0; i < il; i++) {
vals.push($($checkboxes[i]).html());
@@ -43,10 +45,16 @@
return vals.join(', ');
}
$('[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"]').drupalSetSummary(checkboxesSummary);
$(
'[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"]',
).drupalSetSummary(checkboxesSummary);
$('[data-drupal-selector="edit-visibility-request-path"]').drupalSetSummary((context) => {
const $pages = $(context).find('textarea[name="visibility[request_path][pages]"]');
$(
'[data-drupal-selector="edit-visibility-request-path"]',
).drupalSetSummary(context => {
const $pages = $(context).find(
'textarea[name="visibility[request_path][pages]"]',
);
if (!$pages.val()) {
return Drupal.t('Not restricted');
}
@@ -70,7 +78,10 @@
Drupal.behaviors.blockDrag = {
attach(context, settings) {
// tableDrag is required and we should be on the blocks admin page.
if (typeof Drupal.tableDrag === 'undefined' || typeof Drupal.tableDrag.blocks === 'undefined') {
if (
typeof Drupal.tableDrag === 'undefined' ||
typeof Drupal.tableDrag.blocks === 'undefined'
) {
return;
}
@@ -83,19 +94,25 @@
* The jQuery object representing the table row.
*/
function checkEmptyRegions(table, rowObject) {
table.find('tr.region-message').each(function () {
table.find('tr.region-message').each(function() {
const $this = $(this);
// If the dragged row is in this region, but above the message row,
// swap it down one space.
if ($this.prev('tr').get(0) === rowObject.element) {
// Prevent a recursion problem when using the keyboard to move rows
// up.
if ((rowObject.method !== 'keyboard' || rowObject.direction === 'down')) {
if (
rowObject.method !== 'keyboard' ||
rowObject.direction === 'down'
) {
rowObject.swap('after', this);
}
}
// This region has become empty.
if ($this.next('tr').is(':not(.draggable)') || $this.next('tr').length === 0) {
if (
$this.next('tr').is(':not(.draggable)') ||
$this.next('tr').length === 0
) {
$this.removeClass('region-populated').addClass('region-empty');
}
// This region has become populated.
@@ -136,33 +153,40 @@
// Calculate minimum weight.
let weight = -Math.round(table.find('.draggable').length / 2);
// Update the block weights.
table.find(`.region-${region}-message`).nextUntil('.region-title')
.find('select.block-weight').val(() =>
table
.find(`.region-${region}-message`)
.nextUntil('.region-title')
.find('select.block-weight')
.val(
// Increment the weight before assigning it to prevent using the
// absolute minimum available weight. This way we always have an
// unused upper and lower bound, which makes manually setting the
// weights easier for users who prefer to do it that way.
++weight);
() => ++weight,
);
}
const table = $('#blocks');
// Get the blocks tableDrag object.
const tableDrag = Drupal.tableDrag.blocks;
// Add a handler for when a row is swapped, update empty regions.
tableDrag.row.prototype.onSwap = function (swappedRow) {
tableDrag.row.prototype.onSwap = function(swappedRow) {
checkEmptyRegions(table, this);
updateLastPlaced(table, this);
};
// Add a handler so when a row is dropped, update fields dropped into
// new regions.
tableDrag.onDrop = function () {
tableDrag.onDrop = function() {
const dragObject = this;
const $rowElement = $(dragObject.rowObject.element);
// Use "region-message" row instead of "region" row because
// "region-{region_name}-message" is less prone to regexp match errors.
const regionRow = $rowElement.prevAll('tr.region-message').get(0);
const regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
const regionName = regionRow.className.replace(
/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/,
'$2',
);
const regionField = $rowElement.find('select.block-region-select');
// Check whether the newly picked region is available for this block.
if (regionField.find(`option[value=${regionName}]`).length === 0) {
@@ -177,9 +201,16 @@
// Update region and weight fields if the region has been changed.
if (!regionField.is(`.block-region-${regionName}`)) {
const weightField = $rowElement.find('select.block-weight');
const oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
regionField.removeClass(`block-region-${oldRegionName}`).addClass(`block-region-${regionName}`);
weightField.removeClass(`block-weight-${oldRegionName}`).addClass(`block-weight-${regionName}`);
const oldRegionName = weightField[0].className.replace(
/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/,
'$2',
);
regionField
.removeClass(`block-region-${oldRegionName}`)
.addClass(`block-region-${regionName}`);
weightField
.removeClass(`block-weight-${oldRegionName}`)
.addClass(`block-weight-${regionName}`);
regionField.val(regionName);
}
@@ -187,16 +218,22 @@
};
// Add the behavior to each region select list.
$(context).find('select.block-region-select').once('block-region-select')
.on('change', function (event) {
$(context)
.find('select.block-region-select')
.once('block-region-select')
.on('change', function(event) {
// Make our new row and select field.
const row = $(this).closest('tr');
const select = $(this);
// Find the correct region and insert the row as the last in the
// region.
tableDrag.rowObject = new tableDrag.row(row[0]);
const regionMessage = table.find(`.region-${select[0].value}-message`);
const regionItems = regionMessage.nextUntil('.region-message, .region-title');
const regionMessage = table.find(
`.region-${select[0].value}-message`,
);
const regionItems = regionMessage.nextUntil(
'.region-message, .region-title',
);
if (regionItems.length) {
regionItems.last().after(row);
}
@@ -211,7 +248,10 @@
updateLastPlaced(table, row);
// Show unsaved changes warning.
if (!tableDrag.changed) {
$(Drupal.theme('tableDragChangedWarning')).insertBefore(tableDrag.table).hide().fadeIn('slow');
$(Drupal.theme('tableDragChangedWarning'))
.insertBefore(tableDrag.table)
.hide()
.fadeIn('slow');
tableDrag.changed = true;
}
// Remove focus from selectbox.
@@ -219,4 +259,4 @@
});
},
};
}(jQuery, window, Drupal));
})(jQuery, window, Drupal);
@@ -3,6 +3,7 @@
namespace Drupal\block;
use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Component\Plugin\Exception\MissingValueContextException;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableDependencyInterface;
@@ -67,7 +68,6 @@ class BlockAccessControlHandler extends EntityAccessControlHandler implements En
$this->contextRepository = $context_repository;
}
/**
* {@inheritdoc}
*/
@@ -84,12 +84,16 @@ class BlockAccessControlHandler extends EntityAccessControlHandler implements En
else {
$conditions = [];
$missing_context = FALSE;
$missing_value = FALSE;
foreach ($entity->getVisibilityConditions() as $condition_id => $condition) {
if ($condition instanceof ContextAwarePluginInterface) {
try {
$contexts = $this->contextRepository->getRuntimeContexts(array_values($condition->getContextMapping()));
$this->contextHandler->applyContextMapping($condition, $contexts);
}
catch (MissingValueContextException $e) {
$missing_value = TRUE;
}
catch (ContextException $e) {
$missing_context = TRUE;
}
@@ -100,14 +104,15 @@ class BlockAccessControlHandler extends EntityAccessControlHandler implements En
if ($missing_context) {
// If any context is missing then we might be missing cacheable
// metadata, and don't know based on what conditions the block is
// accessible or not. For example, blocks that have a node type
// condition will have a missing context on any non-node route like the
// frontpage.
// @todo Avoid setting max-age 0 for some or all cases, for example by
// treating available contexts without value differently in
// https://www.drupal.org/node/2521956.
// accessible or not. Make sure the result cannot be cached.
$access = AccessResult::forbidden()->setCacheMaxAge(0);
}
elseif ($missing_value) {
// The contexts exist but have no value. Deny access without
// disabling caching. For example the node type condition will have a
// missing context on any non-node route like the frontpage.
$access = AccessResult::forbidden();
}
elseif ($this->resolveConditions($conditions, 'and') !== FALSE) {
// Delegate to the plugin.
$block_plugin = $entity->getPlugin();
@@ -118,12 +123,15 @@ class BlockAccessControlHandler extends EntityAccessControlHandler implements En
}
$access = $block_plugin->access($account, TRUE);
}
catch (MissingValueContextException $e) {
// The contexts exist but have no value. Deny access without
// disabling caching.
$access = AccessResult::forbidden();
}
catch (ContextException $e) {
// Setting access to forbidden if any context is missing for the same
// reasons as with conditions (described in the comment above).
// @todo Avoid setting max-age 0 for some or all cases, for example by
// treating available contexts without value differently in
// https://www.drupal.org/node/2521956.
// If any context is missing then we might be missing cacheable
// metadata, and don't know based on what conditions the block is
// accessible or not. Make sure the result cannot be cached.
$access = AccessResult::forbidden()->setCacheMaxAge(0);
}
}
+3 -2
View File
@@ -239,7 +239,8 @@ class BlockForm extends EntityForm {
// @todo Allow list of conditions to be configured in
// https://www.drupal.org/node/2284687.
$visibility = $this->entity->getVisibility();
foreach ($this->manager->getDefinitionsForContexts($form_state->getTemporaryValue('gathered_contexts')) as $condition_id => $definition) {
$definitions = $this->manager->getFilteredDefinitions('block_ui', $form_state->getTemporaryValue('gathered_contexts'), ['block' => $this->entity]);
foreach ($definitions as $condition_id => $definition) {
// Don't display the current theme condition.
if ($condition_id == 'current_theme') {
continue;
@@ -359,7 +360,7 @@ class BlockForm extends EntityForm {
// Save the settings of the plugin.
$entity->save();
drupal_set_message($this->t('The block configuration has been saved.'));
$this->messenger()->addStatus($this->t('The block configuration has been saved.'));
$form_state->setRedirect(
'block.admin_display_theme',
[
+14 -4
View File
@@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -56,6 +57,13 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
*/
protected $limit = FALSE;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Constructs a new BlockListBuilder object.
*
@@ -68,11 +76,12 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
* @param \Drupal\Core\Form\FormBuilderInterface $form_builder
* The form builder.
*/
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, ThemeManagerInterface $theme_manager, FormBuilderInterface $form_builder) {
public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, ThemeManagerInterface $theme_manager, FormBuilderInterface $form_builder, MessengerInterface $messenger) {
parent::__construct($entity_type, $storage);
$this->themeManager = $theme_manager;
$this->formBuilder = $form_builder;
$this->messenger = $messenger;
}
/**
@@ -83,7 +92,8 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
$entity_type,
$container->get('entity.manager')->getStorage($entity_type->id()),
$container->get('theme.manager'),
$container->get('form_builder')
$container->get('form_builder'),
$container->get('messenger')
);
}
@@ -212,7 +222,7 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
'#theme_wrappers' => [
'container' => [
'#attributes' => ['class' => 'region-title__action'],
]
],
],
'#prefix' => $title,
'#type' => 'link',
@@ -367,7 +377,7 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
$entity->setRegion($entity_values['region']);
$entity->save();
}
drupal_set_message(t('The block settings have been updated.'));
$this->messenger->addStatus($this->t('The block settings have been updated.'));
// Remove any previously set block placement.
$this->request->query->remove('block-placement');
@@ -53,7 +53,7 @@ class BlockController extends ControllerBase {
*/
public function performOperation(BlockInterface $block, $op) {
$block->$op()->save();
drupal_set_message($this->t('The block settings have been updated.'));
$this->messenger()->addStatus($this->t('The block settings have been updated.'));
return $this->redirect('block.admin_display');
}
@@ -101,8 +101,14 @@ class BlockLibraryController extends ControllerBase {
['data' => $this->t('Operations')],
];
$region = $request->query->get('region');
$weight = $request->query->get('weight');
// Only add blocks which work without any available context.
$definitions = $this->blockManager->getDefinitionsForContexts($this->contextRepository->getAvailableContexts());
$definitions = $this->blockManager->getFilteredDefinitions('block_ui', $this->contextRepository->getAvailableContexts(), [
'theme' => $theme,
'region' => $region,
]);
// Order by category, and then by admin label.
$definitions = $this->blockManager->getSortedDefinitions($definitions);
// Filter out definitions that are not intended to be placed by the UI.
@@ -110,8 +116,6 @@ class BlockLibraryController extends ControllerBase {
return empty($definition['_block_ui_hidden']);
});
$region = $request->query->get('region');
$weight = $request->query->get('weight');
$rows = [];
foreach ($definitions as $plugin_id => $plugin_definition) {
$row = [];
@@ -48,7 +48,8 @@ class BlockListController extends EntityListController {
* The current request.
*
* @return array
* A render array as expected by drupal_render().
* A render array as expected by
* \Drupal\Core\Render\RendererInterface::render().
*/
public function listing($theme = NULL, Request $request = NULL) {
$theme = $theme ?: $this->config('system.theme')->get('default');
+7
View File
@@ -17,6 +17,13 @@ use Drupal\Core\Entity\EntityStorageInterface;
* @ConfigEntityType(
* id = "block",
* label = @Translation("Block"),
* label_collection = @Translation("Blocks"),
* label_singular = @Translation("block"),
* label_plural = @Translation("blocks"),
* label_count = @PluralTranslation(
* singular = "@count block",
* plural = "@count blocks",
* ),
* handlers = {
* "access" = "Drupal\block\BlockAccessControlHandler",
* "view_builder" = "Drupal\block\BlockViewBuilder",
@@ -115,7 +115,7 @@ class BlockVisibility extends ProcessPluginBase implements ContainerFactoryPlugi
// anything else -- the block will simply have no PHP or request_path
// visibility configuration.
elseif ($this->skipPHP) {
throw new MigrateSkipRowException();
throw new MigrateSkipRowException(sprintf("The block with bid '%d' from module '%s' will have no PHP or request_path visibility configuration.", $row->getSourceProperty('bid'), $row->getSourceProperty('module'), $destination_property));
}
}
else {
@@ -0,0 +1,71 @@
<?php
namespace Drupal\block\Plugin\migrate\source\d6;
use Drupal\block\Plugin\migrate\source\Block;
use Drupal\migrate\Plugin\migrate\source\SourcePluginBase;
use Drupal\migrate\Row;
/**
* Gets i18n block data from source database.
*
* @MigrateSource(
* id = "d6_block_translation",
* source_module = "i18nblocks"
* )
*/
class BlockTranslation extends Block {
/**
* {@inheritdoc}
*/
public function query() {
// Let the parent set the block table to use, but do not use the parent
// query. Instead build a query so can use an inner join to the selected
// block table.
parent::query();
$query = $this->select('i18n_blocks', 'i18n')
->fields('i18n')
->fields('b', ['bid', 'module', 'delta', 'theme', 'title']);
$query->innerJoin($this->blockTable, 'b', ('b.module = i18n.module AND b.delta = i18n.delta'));
return $query;
}
/**
* {@inheritdoc}
*/
public function fields() {
return [
'bid' => $this->t('The block numeric identifier.'),
'ibid' => $this->t('The i18n_blocks block numeric identifier.'),
'module' => $this->t('The module providing the block.'),
'delta' => $this->t("The block's delta."),
'type' => $this->t('Block type'),
'language' => $this->t('Language for this field.'),
'theme' => $this->t('Which theme the block is placed in.'),
'default_theme' => $this->t('The default theme.'),
'title' => $this->t('Block title.'),
];
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
$row->setSourceProperty('default_theme', $this->defaultTheme);
return SourcePluginBase::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids = parent::getIds();
$ids['module']['alias'] = 'b';
$ids['delta']['alias'] = 'b';
$ids['theme']['alias'] = 'b';
$ids['language']['type'] = 'string';
return $ids;
}
}
@@ -5,4 +5,4 @@ package: Testing
version: VERSION
core: 8.x
dependencies:
- block
- drupal:block
@@ -4,9 +4,8 @@ namespace Drupal\block_test\ContextProvider;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\Core\Session\AccountInterface;
/**
@@ -47,9 +46,8 @@ class MultipleStaticContext implements ContextProviderInterface {
public function getRuntimeContexts(array $unqualified_context_ids) {
$current_user = $this->userStorage->load($this->account->id());
$context1 = new Context(new ContextDefinition('entity:user', 'User A'), $current_user);
$context2 = new Context(new ContextDefinition('entity:user', 'User B'), $current_user);
$context1 = EntityContext::fromEntity($current_user, 'User A');
$context2 = EntityContext::fromEntity($current_user, 'User B');
$cacheability = new CacheableMetadata();
$cacheability->setCacheContexts(['user']);
@@ -17,7 +17,8 @@ class TestMultipleFormController extends ControllerBase {
'form2' => $this->formBuilder()->buildForm('\Drupal\block_test\Form\FavoriteAnimalTestForm', $form_state),
];
// Output all attached placeholders trough drupal_set_message(), so we can
// Output all attached placeholders trough
// \Drupal\Core\Messenger\MessengerInterface::addMessage(), so we can
// see if there's only one in the tests.
$post_render_callable = function ($elements) {
$matches = [];
@@ -26,7 +27,7 @@ class TestMultipleFormController extends ControllerBase {
$action_values = $matches[2];
foreach ($action_values as $action_value) {
drupal_set_message('Form action: ' . $action_value);
$this->messenger()->addStatus('Form action: ' . $action_value);
}
return $elements;
};
@@ -25,7 +25,7 @@ class FavoriteAnimalTestForm extends FormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
$form['favorite_animal'] = [
'#type' => 'textfield',
'#title' => $this->t('Your favorite animal.')
'#title' => $this->t('Your favorite animal.'),
];
$form['submit_animal'] = [
@@ -40,7 +40,7 @@ class FavoriteAnimalTestForm extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message($this->t('Your favorite animal is: @favorite_animal', ['@favorite_animal' => $form['favorite_animal']['#value']]));
$this->messenger()->addStatus($this->t('Your favorite animal is: @favorite_animal', ['@favorite_animal' => $form['favorite_animal']['#value']]));
}
}
@@ -25,7 +25,7 @@ class TestForm extends FormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
$form['email'] = [
'#type' => 'email',
'#title' => $this->t('Your .com email address.')
'#title' => $this->t('Your .com email address.'),
];
$form['show'] = [
@@ -49,7 +49,7 @@ class TestForm extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message($this->t('Your email address is @email', ['@email' => $form['email']['#value']]));
$this->messenger()->addStatus($this->t('Your email address is @email', ['@email' => $form['email']['#value']]));
}
}
@@ -37,7 +37,7 @@ class TestContextAwareBlock extends BlockBase {
*/
protected function blockAccess(AccountInterface $account) {
if ($this->getContextValue('user') instanceof UserInterface) {
drupal_set_message('User context found.');
$this->messenger()->addStatus('User context found.');
}
return parent::blockAccess($account);
@@ -5,5 +5,5 @@ package: Testing
version: VERSION
core: 8.x
dependencies:
- block
- views
- drupal:block
- drupal:views
@@ -2,7 +2,6 @@
namespace Drupal\Tests\block\Functional;
use Drupal\Component\Utility\Unicode;
use Drupal\Tests\BrowserTestBase;
/**
@@ -37,7 +36,7 @@ class BlockHookOperationTest extends BrowserTestBase {
public function testBlockOperationAlter() {
// Add a test block, any block will do.
// Set the machine name so the test_operation link can be built later.
$block_id = Unicode::strtolower($this->randomMachineName(16));
$block_id = mb_strtolower($this->randomMachineName(16));
$this->drupalPlaceBlock('system_powered_by_block', ['id' => $block_id]);
// Get the Block listing.
@@ -15,7 +15,7 @@ class BlockInstallTest extends BrowserTestBase {
// Warm the page cache.
$this->drupalGet('');
$this->assertNoText('Powered by Drupal');
$this->assertNoCacheTag('config:block_list');
$this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', 'config:block_list');
// Install the block module, and place the "Powered by Drupal" block.
$this->container->get('module_installer')->install(['block', 'shortcut']);
@@ -2,7 +2,6 @@
namespace Drupal\Tests\block\Functional;
use Drupal\Component\Utility\Unicode;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
@@ -62,7 +61,7 @@ class BlockLanguageCacheTest extends BrowserTestBase {
// Create a menu in the default language.
$edit['label'] = $this->randomMachineName();
$edit['id'] = Unicode::strtolower($edit['label']);
$edit['id'] = mb_strtolower($edit['label']);
$this->drupalPostForm('admin/structure/menu/add', $edit, t('Save'));
$this->assertText(t('Menu @label has been added.', ['@label' => $edit['label']]));
@@ -164,7 +164,7 @@ class BlockLanguageTest extends BrowserTestBase {
// Change visibility to now depend on content language for this block.
$edit = [
'visibility[language][context_mapping][language]' => '@language.current_language_context:language_content'
'visibility[language][context_mapping][language]' => '@language.current_language_context:language_content',
];
$this->drupalPostForm('admin/structure/block/manage/' . $block_id, $edit, t('Save block'));
@@ -63,7 +63,7 @@ class BlockRenderOrderTest extends BrowserTestBase {
}
$this->drupalGet('');
$test_content = $this->getRawContent('');
$test_content = $this->getSession()->getPage()->getContent();
$controller = $this->container->get('entity_type.manager')->getStorage('block');
foreach ($controller->loadMultiple() as $return_block) {
@@ -146,7 +146,7 @@ class BlockTest extends BlockTestBase {
$block_name = 'system_powered_by_block';
$add_url = Url::fromRoute('block.admin_add', [
'plugin_id' => $block_name,
'theme' => $default_theme
'theme' => $default_theme,
]);
$links = $this->xpath('//a[contains(@href, :href)]', [':href' => $add_url->toString()]);
$this->assertEqual(1, count($links), 'Found one matching link.');
@@ -537,14 +537,14 @@ class BlockTest extends BlockTestBase {
$this->assertEqual($block->getVisibility()['user_role']['roles'], [
$role1->id() => $role1->id(),
$role2->id() => $role2->id()
$role2->id() => $role2->id(),
]);
$role1->delete();
$block = Block::load($block->id());
$this->assertEqual($block->getVisibility()['user_role']['roles'], [
$role2->id() => $role2->id()
$role2->id() => $role2->id(),
]);
}
@@ -0,0 +1,30 @@
<?php
namespace Drupal\Tests\block\Functional\Hal;
use Drupal\Tests\block\Functional\Rest\BlockResourceTestBase;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group hal
*/
class BlockHalJsonAnonTest extends BlockResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
}
@@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\block\Functional\Hal;
use Drupal\Tests\block\Functional\Rest\BlockResourceTestBase;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
*/
class BlockHalJsonBasicAuthTest extends BlockResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal', 'basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\block\Functional\Hal;
use Drupal\Tests\block\Functional\Rest\BlockResourceTestBase;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
*/
class BlockHalJsonCookieTest extends BlockResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['hal'];
/**
* {@inheritdoc}
*/
protected static $format = 'hal_json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/hal+json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,24 @@
<?php
namespace Drupal\Tests\block\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class BlockJsonAnonTest extends BlockResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
}
@@ -0,0 +1,34 @@
<?php
namespace Drupal\Tests\block\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group rest
*/
class BlockJsonBasicAuthTest extends BlockResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\block\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group rest
*/
class BlockJsonCookieTest extends BlockResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,159 @@
<?php
namespace Drupal\Tests\block\Functional\Rest;
use Drupal\block\Entity\Block;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
abstract class BlockResourceTestBase extends EntityResourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block'];
/**
* {@inheritdoc}
*/
protected static $entityTypeId = 'block';
/**
* @var \Drupal\block\BlockInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
switch ($method) {
case 'GET':
$this->entity->setVisibilityConfig('user_role', [])->save();
break;
case 'POST':
$this->grantPermissionsToTestedRole(['administer blocks']);
break;
case 'PATCH':
$this->grantPermissionsToTestedRole(['administer blocks']);
break;
}
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
$block = Block::create([
'plugin' => 'llama_block',
'region' => 'header',
'id' => 'llama',
'theme' => 'classy',
]);
// All blocks can be viewed by the anonymous user by default. An interesting
// side effect of this is that any anonymous user is also able to read the
// corresponding block config entity via REST, even if an authentication
// provider is configured for the block config entity REST resource! In
// other words: Block entities do not distinguish between 'view' as in
// "render on a page" and 'view' as in "read the configuration".
// This prevents that.
// @todo Fix this in https://www.drupal.org/node/2820315.
$block->setVisibilityConfig('user_role', [
'id' => 'user_role',
'roles' => ['non-existing-role' => 'non-existing-role'],
'negate' => FALSE,
'context_mapping' => [
'user' => '@user.current_user_context:current_user',
],
]);
$block->save();
return $block;
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$normalization = [
'uuid' => $this->entity->uuid(),
'id' => 'llama',
'weight' => NULL,
'langcode' => 'en',
'status' => TRUE,
'dependencies' => [
'theme' => [
'classy',
],
],
'theme' => 'classy',
'region' => 'header',
'provider' => NULL,
'plugin' => 'llama_block',
'settings' => [
'id' => 'broken',
'label' => '',
'provider' => 'core',
'label_display' => 'visible',
],
'visibility' => [],
];
return $normalization;
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
// @todo Update in https://www.drupal.org/node/2300677.
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
// @see ::createEntity()
return ['url.site'];
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheTags() {
// Because the 'user.permissions' cache context is missing, the cache tag
// for the anonymous user role is never added automatically.
return array_values(array_diff(parent::getExpectedCacheTags(), ['config:user.role.anonymous']));
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessMessage($method) {
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
return parent::getExpectedUnauthorizedAccessMessage($method);
}
switch ($method) {
case 'GET':
return "You are not authorized to view this block entity.";
default:
return parent::getExpectedUnauthorizedAccessMessage($method);
}
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessCacheability() {
// @see \Drupal\block\BlockAccessControlHandler::checkAccess()
return parent::getExpectedUnauthorizedAccessCacheability()
->setCacheTags([
'4xx-response',
'config:block.block.llama',
'http_response',
static::$auth ? 'user:2' : 'user:0',
])
->setCacheContexts(['user.roles']);
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\block\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockXmlAnonTest extends BlockResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\block\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockXmlBasicAuthTest extends BlockResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\block\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockXmlCookieTest extends BlockResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -10,6 +10,7 @@ use Drupal\FunctionalTests\Update\UpdatePathTestBase;
* @see https://www.drupal.org/node/2811519
*
* @group Update
* @group legacy
*/
class BlockConditionMissingSchemaUpdateTest extends UpdatePathTestBase {
@@ -6,6 +6,7 @@ namespace Drupal\Tests\block\Functional\Update;
* Runs BlockContextMappingUpdateTest with a dump filled with content.
*
* @group Update
* @group legacy
*/
class BlockContextMappingUpdateFilledTest extends BlockContextMappingUpdateTest {
@@ -12,6 +12,7 @@ use Drupal\node\Entity\Node;
* @see https://www.drupal.org/node/2354889
*
* @group Update
* @group legacy
*/
class BlockContextMappingUpdateTest extends UpdatePathTestBase {
@@ -10,6 +10,7 @@ use Drupal\FunctionalTests\Update\UpdatePathTestBase;
* @see https://www.drupal.org/node/2513534
*
* @group Update
* @group legacy
*/
class BlockRemoveDisabledRegionUpdateTest extends UpdatePathTestBase {
@@ -3,14 +3,14 @@
namespace Drupal\Tests\block\FunctionalJavascript;
use Behat\Mink\Element\NodeElement;
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
/**
* Tests the JavaScript functionality of the block add filter.
*
* @group block
*/
class BlockFilterTest extends JavascriptTestBase {
class BlockFilterTest extends WebDriverTestBase {
/**
* {@inheritdoc}
@@ -47,7 +47,8 @@ class BlockRebuildTest extends KernelTestBase {
*/
public function testRebuildNoBlocks() {
block_rebuild();
$messages = drupal_get_messages();
$messages = \Drupal::messenger()->all();
\Drupal::messenger()->deleteAll();
$this->assertEquals([], $messages);
}
@@ -58,7 +59,8 @@ class BlockRebuildTest extends KernelTestBase {
$this->placeBlock('system_powered_by_block', ['region' => 'content']);
block_rebuild();
$messages = drupal_get_messages();
$messages = \Drupal::messenger()->all();
\Drupal::messenger()->deleteAll();
$this->assertEquals([], $messages);
}
@@ -89,7 +91,8 @@ class BlockRebuildTest extends KernelTestBase {
$block1 = Block::load($block1->id());
$block2 = Block::load($block2->id());
$messages = drupal_get_messages();
$messages = \Drupal::messenger()->all();
\Drupal::messenger()->deleteAll();
$expected = ['warning' => [new TranslatableMarkup('The block %info was assigned to the invalid region %region and has been disabled.', ['%info' => $block1->id(), '%region' => 'INVALID'])]];
$this->assertEquals($expected, $messages);
@@ -26,7 +26,7 @@ class BlockStorageUnitTest extends KernelTestBase {
/**
* The block storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface.
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $controller;
@@ -0,0 +1,65 @@
<?php
namespace Drupal\Tests\block\Kernel\Migrate\d6;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
/**
* Tests migration of i18n block translations.
*
* @group migrate_drupal_6
*/
class MigrateBlockContentTranslationTest extends MigrateDrupal6TestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'aggregator',
'book',
'block',
'comment',
'forum',
'views',
'block_content',
'content_translation',
'language',
'statistics',
'taxonomy',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['block']);
$this->installConfig(['block_content']);
$this->installEntitySchema('block_content');
$this->executeMigrations([
'd6_filter_format',
'block_content_type',
'block_content_body_field',
'd6_custom_block',
'd6_user_role',
'd6_block',
'd6_block_translation',
]);
block_rebuild();
}
/**
* Tests the migration of block title translation.
*/
public function testBlockContentTranslation() {
/** @var \Drupal\language\ConfigurableLanguageManagerInterface $language_manager */
$language_manager = $this->container->get('language_manager');
$config = $language_manager->getLanguageConfigOverride('zu', 'block.block.user_1');
$this->assertSame('zu - Navigation', $config->get('settings.label'));
}
}
@@ -116,9 +116,9 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
$visibility = [];
$settings = [
'id' => 'system_menu_block',
'label' => '',
'label' => 'zu - Navigation',
'provider' => 'system',
'label_display' => '0',
'label_display' => 'visible',
'level' => 1,
'depth' => 0,
];
@@ -87,7 +87,7 @@ class BlockTest extends MigrateSqlSourceTestBase {
'schema_version' => '6055',
'weight' => '0',
'info' => 'a:0:{}',
]
],
];
// The expected results.
@@ -104,7 +104,7 @@ class BlockTest extends MigrateSqlSourceTestBase {
'pages' => '',
'title' => 'Test Title 01',
'cache' => -1,
'roles' => [2]
'roles' => [2],
],
[
'bid' => 2,
@@ -118,7 +118,7 @@ class BlockTest extends MigrateSqlSourceTestBase {
'pages' => '<front>',
'title' => 'Test Title 02',
'cache' => -1,
'roles' => [2]
'roles' => [2],
],
];
return $tests;
@@ -0,0 +1,79 @@
<?php
namespace Drupal\Tests\block\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\block\Kernel\Plugin\migrate\source\BlockTest;
/**
* Tests i18n block source plugin.
*
* @covers \Drupal\block\Plugin\migrate\source\d6\BlockTranslation
*
* @group content_translation
*/
class BlockTranslationTest extends BlockTest {
/**
* {@inheritdoc}
*/
public static $modules = ['block'];
/**
* {@inheritdoc}
*/
public function providerSource() {
// Test data is the same as BlockTest, but with the addition of i18n_blocks.
$tests = parent::providerSource();
// The source data.
$tests[0]['source_data']['i18n_blocks'] = [
[
'ibid' => 1,
'module' => 'block',
'delta' => '1',
'type' => 0,
'language' => 'fr',
],
[
'ibid' => 2,
'module' => 'block',
'delta' => '2',
'type' => 0,
'language' => 'zu',
],
];
$tests[0]['source_data']['variables'] = [
[
'name' => 'default_theme',
'value' => 's:7:"garland";',
],
];
// The expected results.
$tests[0]['expected_data'] = [
[
'bid' => 1,
'module' => 'block',
'delta' => '1',
'title' => 'Test Title 01',
'ibid' => 1,
'type' => '0',
'language' => 'fr',
'default_theme' => 'Garland',
],
[
'bid' => 2,
'module' => 'block',
'delta' => '2',
'theme' => 'garland',
'title' => 'Test Title 02',
'ibid' => 2,
'type' => '0',
'language' => 'zu',
'default_theme' => 'Garland',
],
];
return $tests;
}
}
@@ -118,21 +118,21 @@ class BlockRepositoryTest extends UnitTestCase {
public function providerBlocksConfig() {
$blocks_config = [
'block1' => [
AccessResult::allowed(), 'top', 0
AccessResult::allowed(), 'top', 0,
],
// Test a block without access.
'block2' => [
AccessResult::forbidden(), 'bottom', 0
AccessResult::forbidden(), 'bottom', 0,
],
// Test some blocks in the same region with specific weight.
'block4' => [
AccessResult::allowed(), 'bottom', 5
AccessResult::allowed(), 'bottom', 5,
],
'block3' => [
AccessResult::allowed(), 'bottom', 5
AccessResult::allowed(), 'bottom', 5,
],
'block5' => [
AccessResult::allowed(), 'bottom', -5
AccessResult::allowed(), 'bottom', -5,
],
];
@@ -142,7 +142,7 @@ class BlockRepositoryTest extends UnitTestCase {
'top' => ['block1'],
'center' => [],
'bottom' => ['block5', 'block3', 'block4'],
]
],
];
return $test_cases;
}
@@ -4,6 +4,7 @@ namespace Drupal\Tests\block\Unit\Plugin\migrate\process;
use Drupal\block\Plugin\migrate\process\BlockVisibility;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
@@ -80,4 +81,22 @@ class BlockVisibilityTest extends MigrateProcessTestCase {
$this->assertEmpty($transformed_value);
}
/**
* @covers ::transform
*/
public function testTransformException() {
$this->moduleHandler->moduleExists('php')->willReturn(FALSE);
$migration_plugin = $this->prophesize(MigrateProcessInterface::class);
$this->row = $this->getMockBuilder('Drupal\migrate\Row')
->disableOriginalConstructor()
->setMethods(['getSourceProperty'])
->getMock();
$this->row->expects($this->exactly(2))
->method('getSourceProperty')
->willReturnMap([['bid', 99], ['module', 'foobar']]);
$this->plugin = new BlockVisibility(['skip_php' => TRUE], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal());
$this->setExpectedException(MigrateSkipRowException::class, "The block with bid '99' from module 'foobar' will have no PHP or request_path visibility configuration.");
$this->plugin->transform([2, '<?php', []], $this->migrateExecutable, $this->row, 'destinationproperty');
}
}