Update to Drupal 8.2.0. For more information, see https://www.drupal.org/project/drupal/releases/8.2.0
This commit is contained in:
parent
2f563ab520
commit
f1c8716f57
1732 changed files with 52334 additions and 11780 deletions
|
@ -109,12 +109,12 @@ function block_themes_installed($theme_list) {
|
|||
*/
|
||||
function block_theme_initialize($theme) {
|
||||
// Initialize theme's blocks if none already registered.
|
||||
$has_blocks = entity_load_multiple_by_properties('block', array('theme' => $theme));
|
||||
$has_blocks = \Drupal::entityTypeManager()->getStorage('block')->loadByProperties(array('theme' => $theme));
|
||||
if (!$has_blocks) {
|
||||
$default_theme = \Drupal::config('system.theme')->get('default');
|
||||
// Apply only to new theme's visible regions.
|
||||
$regions = system_region_list($theme, REGIONS_VISIBLE);
|
||||
$default_theme_blocks = entity_load_multiple_by_properties('block', array('theme' => $default_theme));
|
||||
$default_theme_blocks = \Drupal::entityTypeManager()->getStorage('block')->loadByProperties(array('theme' => $default_theme));
|
||||
foreach ($default_theme_blocks as $default_theme_block_id => $default_theme_block) {
|
||||
if (strpos($default_theme_block_id, $default_theme . '_') === 0) {
|
||||
$id = str_replace($default_theme, $theme, $default_theme_block_id);
|
||||
|
@ -141,7 +141,7 @@ function block_rebuild() {
|
|||
if ($data->status) {
|
||||
$regions = system_region_list($theme);
|
||||
/** @var \Drupal\block\BlockInterface[] $blocks */
|
||||
$blocks = entity_load_multiple_by_properties('block', ['theme' => $theme]);
|
||||
$blocks = \Drupal::entityTypeManager()->getStorage('block')->loadByProperties(['theme' => $theme]);
|
||||
foreach ($blocks as $block_id => $block) {
|
||||
// Disable blocks in invalid regions.
|
||||
$region = $block->getRegion();
|
||||
|
|
|
@ -63,17 +63,19 @@ process:
|
|||
region:
|
||||
plugin: block_region
|
||||
source:
|
||||
- region
|
||||
- theme
|
||||
- '@theme'
|
||||
region_map:
|
||||
left: sidebar_first
|
||||
right: sidebar_second
|
||||
sidebar_first: sidebar_first
|
||||
sidebar_second: sidebar_second
|
||||
help: help
|
||||
header: header
|
||||
footer: footer
|
||||
- region
|
||||
map:
|
||||
garland:
|
||||
bartik:
|
||||
# Garland 6.x --> Bartik 8.x
|
||||
header: header
|
||||
footer: footer_fifth
|
||||
left: sidebar_first
|
||||
right: sidebar_second
|
||||
# If mapping fails, put the block in the content region.
|
||||
default_value: content
|
||||
weight: weight
|
||||
settings:
|
||||
plugin: block_settings
|
||||
|
|
|
@ -67,17 +67,24 @@ process:
|
|||
region:
|
||||
plugin: block_region
|
||||
source:
|
||||
- region
|
||||
- theme
|
||||
- '@theme'
|
||||
region_map:
|
||||
left: sidebar_first
|
||||
right: sidebar_second
|
||||
sidebar_first: sidebar_first
|
||||
sidebar_second: sidebar_second
|
||||
help: help
|
||||
header: header
|
||||
footer: footer
|
||||
- region
|
||||
map:
|
||||
bartik:
|
||||
bartik:
|
||||
# Bartik 7.x --> Bartik 8.x
|
||||
featured: featured_top
|
||||
triptych_first: featured_bottom_first
|
||||
triptych_middle: featured_bottom_second
|
||||
triptych_last: featured_bottom_third
|
||||
footer_firstcolumn: footer_first
|
||||
footer_secondcolumn: footer_second
|
||||
footer_thirdcolumn: footer_third
|
||||
footer_fourthcolumn: footer_fourth
|
||||
footer: footer_fifth
|
||||
# If mapping fails, put the block in the content region.
|
||||
default_value: content
|
||||
weight: weight
|
||||
settings:
|
||||
plugin: block_settings
|
||||
|
|
|
@ -3,15 +3,18 @@
|
|||
namespace Drupal\block;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Plugin\PluginFormFactoryInterface;
|
||||
use Drupal\Core\Block\BlockPluginInterface;
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Executable\ExecutableManagerInterface;
|
||||
use Drupal\Core\Extension\ThemeHandlerInterface;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Form\SubformState;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Plugin\ContextAwarePluginInterface;
|
||||
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
|
||||
use Drupal\Core\Plugin\PluginWithFormsInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -68,6 +71,13 @@ class BlockForm extends EntityForm {
|
|||
*/
|
||||
protected $contextRepository;
|
||||
|
||||
/**
|
||||
* The plugin form manager.
|
||||
*
|
||||
* @var \Drupal\Core\Plugin\PluginFormFactoryInterface
|
||||
*/
|
||||
protected $pluginFormFactory;
|
||||
|
||||
/**
|
||||
* Constructs a BlockForm object.
|
||||
*
|
||||
|
@ -81,13 +91,16 @@ class BlockForm extends EntityForm {
|
|||
* The language manager.
|
||||
* @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
|
||||
* The theme handler.
|
||||
* @param \Drupal\Core\Plugin\PluginFormFactoryInterface $plugin_form_manager
|
||||
* The plugin form manager.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager, ExecutableManagerInterface $manager, ContextRepositoryInterface $context_repository, LanguageManagerInterface $language, ThemeHandlerInterface $theme_handler) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, ExecutableManagerInterface $manager, ContextRepositoryInterface $context_repository, LanguageManagerInterface $language, ThemeHandlerInterface $theme_handler, PluginFormFactoryInterface $plugin_form_manager) {
|
||||
$this->storage = $entity_manager->getStorage('block');
|
||||
$this->manager = $manager;
|
||||
$this->contextRepository = $context_repository;
|
||||
$this->language = $language;
|
||||
$this->themeHandler = $theme_handler;
|
||||
$this->pluginFormFactory = $plugin_form_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +112,8 @@ class BlockForm extends EntityForm {
|
|||
$container->get('plugin.manager.condition'),
|
||||
$container->get('context.repository'),
|
||||
$container->get('language_manager'),
|
||||
$container->get('theme_handler')
|
||||
$container->get('theme_handler'),
|
||||
$container->get('plugin_form.factory')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -120,7 +134,9 @@ class BlockForm extends EntityForm {
|
|||
$form_state->setTemporaryValue('gathered_contexts', $this->contextRepository->getAvailableContexts());
|
||||
|
||||
$form['#tree'] = TRUE;
|
||||
$form['settings'] = $entity->getPlugin()->buildConfigurationForm(array(), $form_state);
|
||||
$form['settings'] = [];
|
||||
$subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
|
||||
$form['settings'] = $this->getPluginForm($entity->getPlugin())->buildConfigurationForm($form['settings'], $subform_state);
|
||||
$form['visibility'] = $this->buildVisibilityInterface([], $form_state);
|
||||
|
||||
// If creating a new block, calculate a safe default machine name.
|
||||
|
@ -164,6 +180,13 @@ class BlockForm extends EntityForm {
|
|||
);
|
||||
}
|
||||
|
||||
// Hidden weight setting.
|
||||
$weight = $entity->isNew() ? $this->getRequest()->query->get('weight', 0) : $entity->getWeight();
|
||||
$form['weight'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#default_value' => $weight,
|
||||
);
|
||||
|
||||
// Region settings.
|
||||
$entity_region = $entity->getRegion();
|
||||
$region = $entity->isNew() ? $this->getRequest()->query->get('region', $entity_region) : $entity_region;
|
||||
|
@ -278,13 +301,10 @@ class BlockForm extends EntityForm {
|
|||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::validateForm($form, $form_state);
|
||||
|
||||
$form_state->setValue('weight', (int) $form_state->getValue('weight'));
|
||||
// The Block Entity form puts all block plugin form elements in the
|
||||
// settings form element, so just pass that to the block for validation.
|
||||
$settings = (new FormState())->setValues($form_state->getValue('settings'));
|
||||
// Call the plugin validate handler.
|
||||
$this->entity->getPlugin()->validateConfigurationForm($form, $settings);
|
||||
// Update the original form values.
|
||||
$form_state->setValue('settings', $settings->getValues());
|
||||
$this->getPluginForm($this->entity->getPlugin())->validateConfigurationForm($form['settings'], SubformState::createForSubform($form['settings'], $form, $form_state));
|
||||
$this->validateVisibility($form, $form_state);
|
||||
}
|
||||
|
||||
|
@ -308,11 +328,7 @@ class BlockForm extends EntityForm {
|
|||
|
||||
// Allow the condition to validate the form.
|
||||
$condition = $form_state->get(['conditions', $condition_id]);
|
||||
$condition_values = (new FormState())
|
||||
->setValues($values);
|
||||
$condition->validateConfigurationForm($form, $condition_values);
|
||||
// Update the original form values.
|
||||
$form_state->setValue(['visibility', $condition_id], $condition_values->getValues());
|
||||
$condition->validateConfigurationForm($form['visibility'][$condition_id], SubformState::createForSubform($form['visibility'][$condition_id], $form, $form_state));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,37 +341,17 @@ class BlockForm extends EntityForm {
|
|||
$entity = $this->entity;
|
||||
// The Block Entity form puts all block plugin form elements in the
|
||||
// settings form element, so just pass that to the block for submission.
|
||||
// @todo Find a way to avoid this manipulation.
|
||||
$settings = (new FormState())->setValues($form_state->getValue('settings'));
|
||||
|
||||
$sub_form_state = SubformState::createForSubform($form['settings'], $form, $form_state);
|
||||
// Call the plugin submit handler.
|
||||
$entity->getPlugin()->submitConfigurationForm($form, $settings);
|
||||
$block = $entity->getPlugin();
|
||||
$this->getPluginForm($block)->submitConfigurationForm($form, $sub_form_state);
|
||||
// If this block is context-aware, set the context mapping.
|
||||
if ($block instanceof ContextAwarePluginInterface && $block->getContextDefinitions()) {
|
||||
$context_mapping = $settings->getValue('context_mapping', []);
|
||||
$context_mapping = $sub_form_state->getValue('context_mapping', []);
|
||||
$block->setContextMapping($context_mapping);
|
||||
}
|
||||
// Update the original form values.
|
||||
$form_state->setValue('settings', $settings->getValues());
|
||||
|
||||
// Submit visibility condition settings.
|
||||
foreach ($form_state->getValue('visibility') as $condition_id => $values) {
|
||||
// Allow the condition to submit the form.
|
||||
$condition = $form_state->get(['conditions', $condition_id]);
|
||||
$condition_values = (new FormState())
|
||||
->setValues($values);
|
||||
$condition->submitConfigurationForm($form, $condition_values);
|
||||
if ($condition instanceof ContextAwarePluginInterface) {
|
||||
$context_mapping = isset($values['context_mapping']) ? $values['context_mapping'] : [];
|
||||
$condition->setContextMapping($context_mapping);
|
||||
}
|
||||
// Update the original form values.
|
||||
$condition_configuration = $condition->getConfiguration();
|
||||
$form_state->setValue(['visibility', $condition_id], $condition_configuration);
|
||||
// Update the visibility conditions on the block.
|
||||
$entity->getVisibilityConditions()->addInstanceId($condition_id, $condition_configuration);
|
||||
}
|
||||
$this->submitVisibility($form, $form_state);
|
||||
|
||||
// Save the settings of the plugin.
|
||||
$entity->save();
|
||||
|
@ -370,6 +366,36 @@ class BlockForm extends EntityForm {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to independently submit the visibility UI.
|
||||
*
|
||||
* @param array $form
|
||||
* A nested array form elements comprising the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*/
|
||||
protected function submitVisibility(array $form, FormStateInterface $form_state) {
|
||||
foreach ($form_state->getValue('visibility') as $condition_id => $values) {
|
||||
// Allow the condition to submit the form.
|
||||
$condition = $form_state->get(['conditions', $condition_id]);
|
||||
$condition->submitConfigurationForm($form['visibility'][$condition_id], SubformState::createForSubform($form['visibility'][$condition_id], $form, $form_state));
|
||||
|
||||
// Setting conditions' context mappings is the plugins' responsibility.
|
||||
// This code exists for backwards compatibility, because
|
||||
// \Drupal\Core\Condition\ConditionPluginBase::submitConfigurationForm()
|
||||
// did not set its own mappings until Drupal 8.2
|
||||
// @todo Remove the code that sets context mappings in Drupal 9.0.0.
|
||||
if ($condition instanceof ContextAwarePluginInterface) {
|
||||
$context_mapping = isset($values['context_mapping']) ? $values['context_mapping'] : [];
|
||||
$condition->setContextMapping($context_mapping);
|
||||
}
|
||||
|
||||
$condition_configuration = $condition->getConfiguration();
|
||||
// Update the visibility conditions on the block.
|
||||
$this->entity->getVisibilityConditions()->addInstanceId($condition_id, $condition_configuration);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique machine name for a block.
|
||||
*
|
||||
|
@ -402,4 +428,20 @@ class BlockForm extends EntityForm {
|
|||
return $machine_default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the plugin form for a given block and operation.
|
||||
*
|
||||
* @param \Drupal\Core\Block\BlockPluginInterface $block
|
||||
* The block plugin.
|
||||
*
|
||||
* @return \Drupal\Core\Plugin\PluginFormInterface
|
||||
* The plugin form for the block.
|
||||
*/
|
||||
protected function getPluginForm(BlockPluginInterface $block) {
|
||||
if ($block instanceof PluginWithFormsInterface) {
|
||||
return $this->pluginFormFactory->createInstance($block, 'configure');
|
||||
}
|
||||
return $block;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
|
|||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Plugin\ContextAwarePluginInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\block\Entity\Block;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
|
@ -186,7 +187,7 @@ class BlockViewBuilder extends EntityViewBuilder {
|
|||
* A render array with a #pre_render callback to render the block.
|
||||
*/
|
||||
public static function lazyBuilder($entity_id, $view_mode) {
|
||||
return static::buildPreRenderableBlock(entity_load('block', $entity_id), \Drupal::service('module_handler'));
|
||||
return static::buildPreRenderableBlock(Block::load($entity_id), \Drupal::service('module_handler'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@ use Drupal\Core\Controller\ControllerBase;
|
|||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Menu\LocalActionManagerInterface;
|
||||
use Drupal\Core\Plugin\Context\LazyContextRepository;
|
||||
use Drupal\Core\Routing\RedirectDestinationInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -46,6 +47,13 @@ class BlockLibraryController extends ControllerBase {
|
|||
*/
|
||||
protected $localActionManager;
|
||||
|
||||
/**
|
||||
* The redirect destination.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\RedirectDestinationInterface
|
||||
*/
|
||||
protected $redirectDestination;
|
||||
|
||||
/**
|
||||
* Constructs a BlockLibraryController object.
|
||||
*
|
||||
|
@ -57,12 +65,15 @@ class BlockLibraryController extends ControllerBase {
|
|||
* The current route match.
|
||||
* @param \Drupal\Core\Menu\LocalActionManagerInterface $local_action_manager
|
||||
* The local action manager.
|
||||
* @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
|
||||
* The redirect destination.
|
||||
*/
|
||||
public function __construct(BlockManagerInterface $block_manager, LazyContextRepository $context_repository, RouteMatchInterface $route_match, LocalActionManagerInterface $local_action_manager) {
|
||||
public function __construct(BlockManagerInterface $block_manager, LazyContextRepository $context_repository, RouteMatchInterface $route_match, LocalActionManagerInterface $local_action_manager, RedirectDestinationInterface $redirect_destination) {
|
||||
$this->blockManager = $block_manager;
|
||||
$this->routeMatch = $route_match;
|
||||
$this->localActionManager = $local_action_manager;
|
||||
$this->contextRepository = $context_repository;
|
||||
$this->redirectDestination = $redirect_destination;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +84,8 @@ class BlockLibraryController extends ControllerBase {
|
|||
$container->get('plugin.manager.block'),
|
||||
$container->get('context.repository'),
|
||||
$container->get('current_route_match'),
|
||||
$container->get('plugin.manager.menu.local_action')
|
||||
$container->get('plugin.manager.menu.local_action'),
|
||||
$container->get('redirect.destination')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -107,6 +119,7 @@ class BlockLibraryController extends ControllerBase {
|
|||
$definitions = $this->blockManager->getSortedDefinitions($definitions);
|
||||
|
||||
$region = $request->query->get('region');
|
||||
$weight = $request->query->get('weight');
|
||||
$rows = [];
|
||||
foreach ($definitions as $plugin_id => $plugin_definition) {
|
||||
$row = [];
|
||||
|
@ -132,6 +145,13 @@ class BlockLibraryController extends ControllerBase {
|
|||
if ($region) {
|
||||
$links['add']['query']['region'] = $region;
|
||||
}
|
||||
if (isset($weight)) {
|
||||
$links['add']['query']['weight'] = $weight;
|
||||
}
|
||||
$destination = $this->redirectDestination->get();
|
||||
if ($destination) {
|
||||
$links['add']['query']['destination'] = $destination;
|
||||
}
|
||||
$row['operations']['data'] = [
|
||||
'#type' => 'operations',
|
||||
'#links' => $links,
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Drupal\block\Plugin\migrate\process;
|
|||
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Plugin\migrate\process\StaticMap;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
|
@ -13,7 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* id = "block_region"
|
||||
* )
|
||||
*/
|
||||
class BlockRegion extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
class BlockRegion extends StaticMap implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* List of regions, keyed by theme.
|
||||
|
@ -56,7 +56,7 @@ class BlockRegion extends ProcessPluginBase implements ContainerFactoryPluginInt
|
|||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
// Set the destination region, based on the source region and theme as well
|
||||
// as the current destination default theme.
|
||||
list($region, $source_theme, $destination_theme) = $value;
|
||||
list($source_theme, $destination_theme, $region) = $value;
|
||||
|
||||
// Theme is the same on both source and destination, so ensure that the
|
||||
// region exists in the destination theme.
|
||||
|
@ -66,15 +66,8 @@ class BlockRegion extends ProcessPluginBase implements ContainerFactoryPluginInt
|
|||
}
|
||||
}
|
||||
|
||||
// If the source and destination theme are different, try to use the
|
||||
// mappings defined in the configuration.
|
||||
$region_map = $this->configuration['region_map'];
|
||||
if (isset($region_map[$region])) {
|
||||
return $region_map[$region];
|
||||
}
|
||||
|
||||
// Oh well, we tried. Put the block in the main content region.
|
||||
return 'content';
|
||||
// Fall back to static mapping.
|
||||
return parent::transform($value, $migrate_executable, $row, $destination_property);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@ class BlockTheme extends ProcessPluginBase implements ContainerFactoryPluginInte
|
|||
*/
|
||||
protected $configFactory;
|
||||
|
||||
/**
|
||||
* Contains the system.theme configuration object.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Config
|
||||
*/
|
||||
/**
|
||||
* Contains the system.theme configuration object.
|
||||
*
|
||||
* @var \Drupal\Core\Config\Config
|
||||
*/
|
||||
protected $themeConfig;
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,7 +63,7 @@ class BlockCacheTest extends WebTestBase {
|
|||
$this->normalUserAlt->save();
|
||||
|
||||
// Enable our test block.
|
||||
$this->block = $this->drupalPlaceBlock('test_cache');
|
||||
$this->block = $this->drupalPlaceBlock('test_cache');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,7 +25,7 @@ class BlockFormInBlockTest extends WebTestBase {
|
|||
parent::setUp();
|
||||
|
||||
// Enable our test block.
|
||||
$this->drupalPlaceBlock('test_form_in_block');
|
||||
$this->drupalPlaceBlock('test_form_in_block');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\block\Tests;
|
|||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
|
@ -127,6 +128,94 @@ class BlockTest extends BlockTestBase {
|
|||
$this->assertNoText($title, 'Block was not displayed to anonymous users on the front page.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a block from the library page with a destination query string.
|
||||
*/
|
||||
public function testAddBlockFromLibrary() {
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
$help_url = Url::fromRoute('help.page', ['name' => 'block']);
|
||||
// Set up the request so we land on the block help page after creation.
|
||||
$options = [
|
||||
'query' => [
|
||||
'region' => 'sidebar_first',
|
||||
'destination' => $help_url->toString(),
|
||||
],
|
||||
];
|
||||
$this->drupalGet(Url::fromRoute('block.admin_library', ['theme' => $default_theme], $options));
|
||||
|
||||
$block_name = 'system_powered_by_block';
|
||||
$add_url = Url::fromRoute('block.admin_add', ['plugin_id' => $block_name, 'theme' => $default_theme]);
|
||||
$links = $this->xpath('//a[contains(@href, :href)]', [':href' => $add_url->toString()]);
|
||||
$this->assertEqual(1, count($links), 'Found one matching link');
|
||||
|
||||
list($path, $query_string) = explode('?', $links[0]['href'], 2);
|
||||
parse_str($query_string, $query_parts);
|
||||
$this->assertEqual(t('Place block'), (string) $links[0]);
|
||||
$this->assertEqual($help_url->toString(), $query_parts['destination'], 'Expected destination query string is in href');
|
||||
|
||||
// Create a random title for the block.
|
||||
$title = $this->randomMachineName(8);
|
||||
$block_id = strtolower($this->randomMachineName(8));
|
||||
$edit = [
|
||||
'id' => $block_id,
|
||||
'settings[label]' => $title,
|
||||
];
|
||||
// Create the block using the link parsed from the library page.
|
||||
$this->drupalPostForm($this->getAbsoluteUrl($links[0]['href']), $edit, t('Save block'));
|
||||
// Verify that we are redirected according to the original request.
|
||||
$this->assertUrl($help_url);
|
||||
|
||||
// Ensure that the block was created.
|
||||
/** @var \Drupal\block\BlockInterface $block */
|
||||
$block = Block::load($block_id);
|
||||
$this->assertEqual($title, $block->label(), 'Found the block with expected title.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a block from the library page with a weight query string.
|
||||
*/
|
||||
public function testAddBlockFromLibraryWithWeight() {
|
||||
$default_theme = $this->config('system.theme')->get('default');
|
||||
// Test one positive, zero, and one negative weight.
|
||||
foreach (['7', '0', '-9'] as $weight) {
|
||||
$options = [
|
||||
'query' => [
|
||||
'region' => 'sidebar_first',
|
||||
'weight' => $weight,
|
||||
],
|
||||
];
|
||||
$this->drupalGet(Url::fromRoute('block.admin_library', ['theme' => $default_theme], $options));
|
||||
|
||||
$block_name = 'system_powered_by_block';
|
||||
$add_url = Url::fromRoute('block.admin_add', [
|
||||
'plugin_id' => $block_name,
|
||||
'theme' => $default_theme
|
||||
]);
|
||||
$links = $this->xpath('//a[contains(@href, :href)]', [':href' => $add_url->toString()]);
|
||||
$this->assertEqual(1, count($links), 'Found one matching link.');
|
||||
$this->assertEqual(t('Place block'), (string) $links[0], 'Found the expected link text.');
|
||||
|
||||
list($path, $query_string) = explode('?', $links[0]['href'], 2);
|
||||
parse_str($query_string, $query_parts);
|
||||
$this->assertEqual($weight, $query_parts['weight'], 'Found the expected weight query string.');
|
||||
|
||||
// Create a random title for the block.
|
||||
$title = $this->randomMachineName(8);
|
||||
$block_id = strtolower($this->randomMachineName(8));
|
||||
$edit = [
|
||||
'id' => $block_id,
|
||||
'settings[label]' => $title,
|
||||
];
|
||||
// Create the block using the link parsed from the library page.
|
||||
$this->drupalPostForm($this->getAbsoluteUrl($links[0]['href']), $edit, t('Save block'));
|
||||
|
||||
// Ensure that the block was created with the expected weight.
|
||||
/** @var \Drupal\block\BlockInterface $block */
|
||||
$block = Block::load($block_id);
|
||||
$this->assertEqual($weight, $block->getWeight(), 'Found the block with expected weight.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test configuring and moving a module-define block to specific regions.
|
||||
*/
|
||||
|
|
|
@ -288,4 +288,20 @@ class BlockUiTest extends WebTestBase {
|
|||
$this->assertUrl('admin/structure/block/list/classy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if validation errors are passed plugin form to the parent form.
|
||||
*/
|
||||
public function testBlockValidateErrors() {
|
||||
$this->drupalPostForm('admin/structure/block/add/test_settings_validation/classy', ['settings[digits]' => 'abc'], t('Save block'));
|
||||
|
||||
$arguments = [':message' => 'Only digits are allowed'];
|
||||
$pattern = '//div[contains(@class,"messages messages--error")]/div[contains(text()[2],:message)]';
|
||||
$elements = $this->xpath($pattern, $arguments);
|
||||
$this->assertTrue($elements, 'Plugin error message found in parent form.');
|
||||
|
||||
$error_class_pattern = '//div[contains(@class,"form-item-settings-digits")]/input[contains(@class,"error")]';
|
||||
$error_class = $this->xpath($error_class_pattern);
|
||||
$this->assertTrue($error_class, 'Plugin error class found in parent form.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\block_test\Plugin\Block;
|
||||
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
|
||||
/**
|
||||
* Provides a block with multiple forms.
|
||||
*
|
||||
* @Block(
|
||||
* id = "test_multiple_forms_block",
|
||||
* forms = {
|
||||
* "secondary" = "\Drupal\block_test\PluginForm\EmptyBlockForm"
|
||||
* },
|
||||
* admin_label = @Translation("Multiple forms test block")
|
||||
* )
|
||||
*/
|
||||
class TestMultipleFormsBlock extends BlockBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\block_test\Plugin\Block;
|
||||
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides a test settings validation block.
|
||||
*
|
||||
* @Block(
|
||||
* id = "test_settings_validation",
|
||||
* admin_label = @Translation("Test settings validation block"),
|
||||
* )
|
||||
*/
|
||||
class TestSettingsValidationBlock extends BlockBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function blockForm($form, FormStateInterface $form_state) {
|
||||
return ['digits' => ['#type' => 'textfield']] + $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function blockValidate($form, FormStateInterface $form_state) {
|
||||
if (!ctype_digit($form_state->getValue('digits'))) {
|
||||
$form_state->setErrorByName('digits', $this->t('Only digits are allowed'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
return ['#markup' => 'foo'];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\block_test\PluginForm;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\PluginFormBase;
|
||||
|
||||
/**
|
||||
* Provides a form for a block that is empty.
|
||||
*/
|
||||
class EmptyBlockForm extends PluginFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
// Intentionally empty.
|
||||
}
|
||||
|
||||
}
|
|
@ -49,6 +49,7 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
|
|||
'd6_user_role',
|
||||
'd6_block',
|
||||
]);
|
||||
block_rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,18 +69,21 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
|
|||
* The block label.
|
||||
* @param string $label_display
|
||||
* The block label display setting.
|
||||
* @param bool $status
|
||||
* (optional) Whether the block is expected to be enabled.
|
||||
*/
|
||||
public function assertEntity($id, $visibility, $region, $theme, $weight, $label, $label_display) {
|
||||
public function assertEntity($id, $visibility, $region, $theme, $weight, $label, $label_display, $status = TRUE) {
|
||||
$block = Block::load($id);
|
||||
$this->assertTrue($block instanceof Block);
|
||||
$this->assertIdentical($visibility, $block->getVisibility());
|
||||
$this->assertIdentical($region, $block->getRegion());
|
||||
$this->assertIdentical($theme, $block->getTheme());
|
||||
$this->assertIdentical($weight, $block->getWeight());
|
||||
$this->assertSame($visibility, $block->getVisibility());
|
||||
$this->assertSame($region, $block->getRegion());
|
||||
$this->assertSame($theme, $block->getTheme());
|
||||
$this->assertSame($weight, $block->getWeight());
|
||||
$this->assertSame($status, $block->status());
|
||||
|
||||
$config = $this->config('block.block.' . $id);
|
||||
$this->assertIdentical($label, $config->get('settings.label'));
|
||||
$this->assertIdentical($label_display, $config->get('settings.label_display'));
|
||||
$this->assertSame($label, $config->get('settings.label'));
|
||||
$this->assertSame($label_display, $config->get('settings.label_display'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,7 +126,7 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
|
|||
$visibility['request_path']['id'] = 'request_path';
|
||||
$visibility['request_path']['negate'] = TRUE;
|
||||
$visibility['request_path']['pages'] = '/node/1';
|
||||
$this->assertEntity('system', $visibility, 'footer', 'bartik', -5, '', '0');
|
||||
$this->assertEntity('system', $visibility, 'footer_fifth', 'bartik', -5, '', '0');
|
||||
|
||||
// Check menu blocks
|
||||
$visibility = [];
|
||||
|
@ -137,7 +141,10 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
|
|||
$visibility['request_path']['id'] = 'request_path';
|
||||
$visibility['request_path']['negate'] = FALSE;
|
||||
$visibility['request_path']['pages'] = '/node';
|
||||
$this->assertEntity('block_1', $visibility, 'sidebar_second', 'bluemarine', -4, 'Another Static Block', 'visible');
|
||||
// bluemarine does not exist in Drupal 8 and the d6_block migration defines
|
||||
// no mapping for its regions, so this block should have been defaulted
|
||||
// to the 'content' region.
|
||||
$this->assertEntity('block_1', $visibility, 'content', 'bluemarine', -4, 'Another Static Block', 'visible');
|
||||
|
||||
$visibility = [];
|
||||
$this->assertEntity('block_2', $visibility, 'right', 'test_theme', -7, '', '0');
|
||||
|
|
|
@ -13,7 +13,7 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
|||
*/
|
||||
class MigrateBlockTest extends MigrateDrupal7TestBase {
|
||||
|
||||
/**
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
|
@ -53,6 +53,7 @@ class MigrateBlockTest extends MigrateDrupal7TestBase {
|
|||
'd7_custom_block',
|
||||
'd7_block',
|
||||
]);
|
||||
block_rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,29 +77,32 @@ class MigrateBlockTest extends MigrateDrupal7TestBase {
|
|||
* The block label.
|
||||
* @param string $label_display
|
||||
* The block label display setting.
|
||||
* @param bool $status
|
||||
* (optional) Whether the block is expected to be enabled.
|
||||
*/
|
||||
public function assertEntity($id, $plugin_id, array $roles, $pages, $region, $theme, $weight, $label, $label_display) {
|
||||
public function assertEntity($id, $plugin_id, array $roles, $pages, $region, $theme, $weight, $label, $label_display, $status = TRUE) {
|
||||
$block = Block::load($id);
|
||||
$this->assertTrue($block instanceof Block);
|
||||
/** @var \Drupal\block\BlockInterface $block */
|
||||
$this->assertIdentical($plugin_id, $block->getPluginId());
|
||||
$this->assertSame($plugin_id, $block->getPluginId());
|
||||
|
||||
$visibility = $block->getVisibility();
|
||||
if ($roles) {
|
||||
$this->assertIdentical($roles, array_values($visibility['user_role']['roles']));
|
||||
$this->assertIdentical('@user.current_user_context:current_user', $visibility['user_role']['context_mapping']['user']);
|
||||
$this->assertSame($roles, array_values($visibility['user_role']['roles']));
|
||||
$this->assertSame('@user.current_user_context:current_user', $visibility['user_role']['context_mapping']['user']);
|
||||
}
|
||||
if ($pages) {
|
||||
$this->assertIdentical($pages, $visibility['request_path']['pages']);
|
||||
$this->assertSame($pages, $visibility['request_path']['pages']);
|
||||
}
|
||||
|
||||
$this->assertIdentical($region, $block->getRegion());
|
||||
$this->assertIdentical($theme, $block->getTheme());
|
||||
$this->assertIdentical($weight, $block->getWeight());
|
||||
$this->assertSame($region, $block->getRegion());
|
||||
$this->assertSame($theme, $block->getTheme());
|
||||
$this->assertSame($weight, $block->getWeight());
|
||||
$this->assertSame($status, $block->status());
|
||||
|
||||
$config = $this->config('block.block.' . $id);
|
||||
$this->assertIdentical($label, $config->get('settings.label'));
|
||||
$this->assertIdentical($label_display, $config->get('settings.label_display'));
|
||||
$this->assertSame($label, $config->get('settings.label'));
|
||||
$this->assertSame($label_display, $config->get('settings.label_display'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,7 +112,7 @@ class MigrateBlockTest extends MigrateDrupal7TestBase {
|
|||
$this->assertEntity('bartik_system_main', 'system_main_block', [], '', 'content', 'bartik', 0, '', '0');
|
||||
$this->assertEntity('bartik_search_form', 'search_form_block', [], '', 'sidebar_first', 'bartik', -1, '', '0');
|
||||
$this->assertEntity('bartik_user_login', 'user_login_block', [], '', 'sidebar_first', 'bartik', 0, '', '0');
|
||||
$this->assertEntity('bartik_system_powered_by', 'system_powered_by_block', [], '', 'footer', 'bartik', 10, '', '0');
|
||||
$this->assertEntity('bartik_system_powered_by', 'system_powered_by_block', [], '', 'footer_fifth', 'bartik', 10, '', '0');
|
||||
$this->assertEntity('seven_system_main', 'system_main_block', [], '', 'content', 'seven', 0, '', '0');
|
||||
$this->assertEntity('seven_user_login', 'user_login_block', [], '', 'content', 'seven', 10, '', '0');
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\Tests\block\Unit;
|
||||
|
||||
use Drupal\block\BlockForm;
|
||||
use Drupal\Core\Plugin\PluginFormFactoryInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -54,6 +55,13 @@ class BlockFormTest extends UnitTestCase {
|
|||
*/
|
||||
protected $contextRepository;
|
||||
|
||||
/**
|
||||
* The plugin form manager.
|
||||
*
|
||||
* @var \Drupal\Core\Plugin\PluginFormFactoryInterface|\Prophecy\Prophecy\ProphecyInterface
|
||||
*/
|
||||
protected $pluginFormFactory;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -71,6 +79,7 @@ class BlockFormTest extends UnitTestCase {
|
|||
->method('getStorage')
|
||||
->will($this->returnValue($this->storage));
|
||||
|
||||
$this->pluginFormFactory = $this->prophesize(PluginFormFactoryInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +108,7 @@ class BlockFormTest extends UnitTestCase {
|
|||
->method('getQuery')
|
||||
->will($this->returnValue($query));
|
||||
|
||||
$block_form_controller = new BlockForm($this->entityManager, $this->conditionManager, $this->contextRepository, $this->language, $this->themeHandler);
|
||||
$block_form_controller = new BlockForm($this->entityManager, $this->conditionManager, $this->contextRepository, $this->language, $this->themeHandler, $this->pluginFormFactory->reveal());
|
||||
|
||||
// Ensure that the block with just one other instance gets the next available
|
||||
// name suggestion.
|
||||
|
|
|
@ -18,7 +18,7 @@ class BlockRegionTest extends UnitTestCase {
|
|||
*
|
||||
* @param array $value
|
||||
* The value to transform.
|
||||
* @param \Drupal\migrate\Row|NULL $row
|
||||
* @param \Drupal\migrate\Row|null $row
|
||||
* (optional) The mocked row.
|
||||
*
|
||||
* @return array|string
|
||||
|
@ -30,14 +30,20 @@ class BlockRegionTest extends UnitTestCase {
|
|||
$row = $this->prophesize(Row::class)->reveal();
|
||||
}
|
||||
|
||||
$regions = array(
|
||||
'bartik' => array(
|
||||
'triptych_first' => 'Triptych first',
|
||||
'triptych_second' => 'Triptych second',
|
||||
'triptych_third' => 'Triptych third',
|
||||
),
|
||||
);
|
||||
$plugin = new BlockRegion(['region_map' => []], 'block_region', [], $regions);
|
||||
$configuration = [
|
||||
'map' => [
|
||||
'bartik' => [
|
||||
'bartik' => [
|
||||
'triptych_first' => 'triptych_first',
|
||||
'triptych_middle' => 'triptych_second',
|
||||
'triptych_last' => 'triptych_third',
|
||||
],
|
||||
],
|
||||
],
|
||||
'default_value' => 'content',
|
||||
];
|
||||
|
||||
$plugin = new BlockRegion($configuration, 'block_region', [], $configuration['map']['bartik']['bartik']);
|
||||
return $plugin->transform($value, $executable, $row, 'foo');
|
||||
}
|
||||
|
||||
|
@ -48,7 +54,7 @@ class BlockRegionTest extends UnitTestCase {
|
|||
* @covers ::transform
|
||||
*/
|
||||
public function testTransformSameThemeRegionExists() {
|
||||
$this->assertSame('triptych_second', $this->transform(['triptych_second', 'bartik', 'bartik']));
|
||||
$this->assertSame('triptych_second', $this->transform(['bartik', 'bartik', 'triptych_middle']));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +64,7 @@ class BlockRegionTest extends UnitTestCase {
|
|||
* @covers ::transform
|
||||
*/
|
||||
public function testTransformSameThemeRegionNotExists() {
|
||||
$this->assertSame('content', $this->transform(['footer', 'bartik', 'bartik']));
|
||||
$this->assertSame('content', $this->transform(['bartik', 'bartik', 'footer']));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue