Issue #2286357 by tim.plunkett: Introduce Display Variants, use for the block rendering flow.
parent
234ed4f894
commit
539061c75b
|
@ -312,3 +312,20 @@ condition.plugin:
|
|||
label: 'Context assignments'
|
||||
sequence:
|
||||
- type: string
|
||||
|
||||
display_variant.plugin:
|
||||
type: mapping
|
||||
label: 'Display variant'
|
||||
mapping:
|
||||
id:
|
||||
type: string
|
||||
label: 'ID'
|
||||
label:
|
||||
type: label
|
||||
label: 'Label'
|
||||
weight:
|
||||
type: integer
|
||||
label: 'Weight'
|
||||
uuid:
|
||||
type: string
|
||||
label: 'UUID'
|
||||
|
|
|
@ -263,6 +263,9 @@ services:
|
|||
plugin.manager.menu.contextual_link:
|
||||
class: Drupal\Core\Menu\ContextualLinkManager
|
||||
arguments: ['@controller_resolver', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user', '@request_stack']
|
||||
plugin.manager.display_variant:
|
||||
class: Drupal\Core\Display\VariantManager
|
||||
parent: default_plugin_manager
|
||||
plugin.cache_clearer:
|
||||
class: Drupal\Core\Plugin\CachedDiscoveryClearer
|
||||
request:
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Display\Annotation\DisplayVariant.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Display\Annotation;
|
||||
|
||||
use Drupal\Component\Annotation\Plugin;
|
||||
|
||||
/**
|
||||
* Defines a display variant annotation object.
|
||||
*
|
||||
* Display variants are used to dictate the output of a given Display, which
|
||||
* can be used to control the output of many parts of Drupal. For example, the
|
||||
* FullPageVariant is used by the Block module to control regions and output
|
||||
* block content placed in those regions.
|
||||
*
|
||||
* Variants are usually chosen by some selection criteria, and are instantiated
|
||||
* directly. Each variant must define its own approach to rendering, and can
|
||||
* either load its own data or be injected with data from another Display
|
||||
* object.
|
||||
*
|
||||
* @todo: Revise description when/if Displays are added to core:
|
||||
* https://www.drupal.org/node/2292733
|
||||
*
|
||||
* @see \Drupal\Core\Display\VariantInterface
|
||||
* @see \Drupal\Core\Display\VariantManager
|
||||
*
|
||||
* @Annotation
|
||||
*/
|
||||
class DisplayVariant extends Plugin {
|
||||
|
||||
/**
|
||||
* The plugin ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* The administrative label.
|
||||
*
|
||||
* @var \Drupal\Core\Annotation\Translation
|
||||
*
|
||||
* @ingroup plugin_translatable
|
||||
*/
|
||||
public $admin_label = '';
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Display\VariantBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Display;
|
||||
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\Core\Plugin\PluginDependencyTrait;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Provides a base class for DisplayVariant plugins.
|
||||
*/
|
||||
abstract class VariantBase extends PluginBase implements VariantInterface {
|
||||
|
||||
use PluginDependencyTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->setConfiguration($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function label() {
|
||||
return $this->configuration['label'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function adminLabel() {
|
||||
return $this->pluginDefinition['admin_label'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function id() {
|
||||
return $this->configuration['uuid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWeight() {
|
||||
return (int) $this->configuration['weight'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setWeight($weight) {
|
||||
$this->configuration['weight'] = (int) $weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
'id' => $this->getPluginId(),
|
||||
) + $this->configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setConfiguration(array $configuration) {
|
||||
$this->configuration = $configuration + $this->defaultConfiguration();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return array(
|
||||
'label' => '',
|
||||
'uuid' => '',
|
||||
'weight' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, array &$form_state) {
|
||||
$form['label'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Label'),
|
||||
'#description' => $this->t('The label for this display variant.'),
|
||||
'#default_value' => $this->label(),
|
||||
'#maxlength' => '255',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, array &$form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, array &$form_state) {
|
||||
$this->configuration['label'] = $form_state['values']['label'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access(AccountInterface $account = NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Display\VariantInterface.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Display;
|
||||
|
||||
use Drupal\Component\Plugin\ConfigurablePluginInterface;
|
||||
use Drupal\Component\Plugin\PluginInspectionInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Provides an interface for DisplayVariant plugins.
|
||||
*
|
||||
* @see \Drupal\Core\Display\Annotation\DisplayVariant
|
||||
* @see \Drupal\Core\Display\VariantManager
|
||||
*/
|
||||
interface VariantInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
|
||||
|
||||
/**
|
||||
* Returns the user-facing display variant label.
|
||||
*
|
||||
* @return string
|
||||
* The display variant label.
|
||||
*/
|
||||
public function label();
|
||||
|
||||
/**
|
||||
* Returns the admin-facing display variant label.
|
||||
*
|
||||
* This is for the type of display variant, not the configured variant itself.
|
||||
*
|
||||
* @return string
|
||||
* The display variant administrative label.
|
||||
*/
|
||||
public function adminLabel();
|
||||
|
||||
/**
|
||||
* Returns the unique ID for the display variant.
|
||||
*
|
||||
* @return string
|
||||
* The display variant ID.
|
||||
*/
|
||||
public function id();
|
||||
|
||||
/**
|
||||
* Returns the weight of the display variant.
|
||||
*
|
||||
* @return int
|
||||
* The display variant weight.
|
||||
*/
|
||||
public function getWeight();
|
||||
|
||||
/**
|
||||
* Sets the weight of the display variant.
|
||||
*
|
||||
* @param int $weight
|
||||
* The weight to set.
|
||||
*/
|
||||
public function setWeight($weight);
|
||||
|
||||
/**
|
||||
* Determines if this display variant is accessible.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* (optional) The user for which to check access, or NULL to check access
|
||||
* for the current user. Defaults to NULL.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if this display variant is accessible, FALSE otherwise.
|
||||
*/
|
||||
public function access(AccountInterface $account = NULL);
|
||||
|
||||
/**
|
||||
* Builds and returns the renderable array for the display variant.
|
||||
*
|
||||
* @return array
|
||||
* A render array for the display variant.
|
||||
*/
|
||||
public function build();
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Display\VariantManager.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Display;
|
||||
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Plugin\DefaultPluginManager;
|
||||
|
||||
/**
|
||||
* Manages discovery of display variant plugins.
|
||||
*
|
||||
* @see \Drupal\Core\Display\Annotation\DisplayVariant
|
||||
* @see \Drupal\Core\Display\VariantInterface
|
||||
*/
|
||||
class VariantManager extends DefaultPluginManager {
|
||||
|
||||
/**
|
||||
* Constructs a new VariantManager.
|
||||
*
|
||||
* @param \Traversable $namespaces
|
||||
* An object that implements \Traversable which contains the root paths
|
||||
* keyed by the corresponding namespace to look for plugin implementations.
|
||||
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
|
||||
* Cache backend instance to use.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler to invoke the alter hook with.
|
||||
*/
|
||||
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
|
||||
parent::__construct('Plugin/DisplayVariant', $namespaces, $module_handler, 'Drupal\Core\Display\Annotation\DisplayVariant');
|
||||
|
||||
$this->setCacheBackend($cache_backend, 'variant_plugins');
|
||||
$this->alterInfo('display_variant_plugin');
|
||||
}
|
||||
|
||||
}
|
|
@ -86,22 +86,11 @@ function block_page_build(&$page) {
|
|||
// Fetch a list of regions for the current theme.
|
||||
$all_regions = system_region_list($theme);
|
||||
if (\Drupal::routeMatch()->getRouteName() != 'block.admin_demo') {
|
||||
// Load all region content assigned via blocks.
|
||||
foreach (array_keys($all_regions) as $region) {
|
||||
// Assign blocks to region.
|
||||
if ($blocks = block_get_blocks_by_region($region)) {
|
||||
$page[$region] = $blocks;
|
||||
}
|
||||
}
|
||||
// Once we've finished attaching all blocks to the page, clear the static
|
||||
// cache to allow modules to alter the block list differently in different
|
||||
// contexts. For example, any code that triggers hook_page_build() more
|
||||
// than once in the same page request may need to alter the block list
|
||||
// differently each time, so that only certain parts of the page are
|
||||
// actually built. We do not clear the cache any earlier than this, though,
|
||||
// because it is used each time block_get_blocks_by_region() gets called
|
||||
// above.
|
||||
drupal_static_reset('block_list');
|
||||
// Create a full page display variant, which will load blocks into their
|
||||
// regions.
|
||||
$page += \Drupal::service('plugin.manager.display_variant')
|
||||
->createInstance('full_page')
|
||||
->build();
|
||||
}
|
||||
else {
|
||||
// Append region description if we are rendering the regions demo page.
|
||||
|
@ -123,33 +112,6 @@ function block_page_build(&$page) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a renderable array of a region containing all enabled blocks.
|
||||
*
|
||||
* @param $region
|
||||
* The requested region.
|
||||
*
|
||||
* @return
|
||||
* A renderable array of a region containing all enabled blocks.
|
||||
*/
|
||||
function block_get_blocks_by_region($region) {
|
||||
$build = array();
|
||||
if ($list = block_list($region)) {
|
||||
foreach ($list as $key => $block) {
|
||||
if ($block->access('view')) {
|
||||
$build[$key] = entity_view($block, 'block');
|
||||
}
|
||||
}
|
||||
// If none of the blocks in this region are visible, then don't set anything
|
||||
// else in the render array, because that would cause the region to show up.
|
||||
if (!empty($build)) {
|
||||
// block_list() already returned the blocks in sorted order.
|
||||
$build['#sorted'] = TRUE;
|
||||
}
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of block class instances by theme.
|
||||
*
|
||||
|
@ -240,43 +202,6 @@ function block_theme_initialize($theme) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all blocks in the specified region for the current user.
|
||||
*
|
||||
* @param $region
|
||||
* The name of a region.
|
||||
*
|
||||
* @return
|
||||
* An array of block objects, indexed with the configuration object name
|
||||
* that represents the configuration. If you are displaying your blocks in
|
||||
* one or two sidebars, you may check whether this array is empty to see
|
||||
* how many columns are going to be displayed.
|
||||
*/
|
||||
function block_list($region) {
|
||||
$blocks = &drupal_static(__FUNCTION__);
|
||||
|
||||
if (!isset($blocks)) {
|
||||
global $theme;
|
||||
$blocks = array();
|
||||
foreach (entity_load_multiple_by_properties('block', array('theme' => $theme)) as $block_id => $block) {
|
||||
// Onlye include valid blocks in the list.
|
||||
// @todo Remove this check as part of https://drupal.org/node/1776830.
|
||||
if ($block->getPlugin()) {
|
||||
$blocks[$block->get('region')][$block_id] = $block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create an empty array if there are no entries.
|
||||
if (!isset($blocks[$region])) {
|
||||
$blocks[$region] = array();
|
||||
}
|
||||
|
||||
uasort($blocks[$region], 'Drupal\block\Entity\Block::sort');
|
||||
|
||||
return $blocks[$region];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_rebuild().
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\block\Plugin\DisplayVariant\FullPageVariant.
|
||||
*/
|
||||
|
||||
namespace Drupal\block\Plugin\DisplayVariant;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityViewBuilderInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Display\VariantBase;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Theme\ThemeNegotiatorInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a display variant that represents the full page.
|
||||
*
|
||||
* @DisplayVariant(
|
||||
* id = "full_page",
|
||||
* admin_label = @Translation("Full page")
|
||||
* )
|
||||
*/
|
||||
class FullPageVariant extends VariantBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The block storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface
|
||||
*/
|
||||
protected $blockStorage;
|
||||
|
||||
/**
|
||||
* The block view builder.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityViewBuilderInterface
|
||||
*/
|
||||
protected $blockViewBuilder;
|
||||
|
||||
/**
|
||||
* The current theme.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $theme;
|
||||
|
||||
/**
|
||||
* The current route match.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\RouteMatchInterface
|
||||
*/
|
||||
protected $routeMatch;
|
||||
|
||||
/**
|
||||
* The theme negotiator.
|
||||
*
|
||||
* @var \Drupal\Core\Theme\ThemeNegotiatorInterface
|
||||
*/
|
||||
protected $themeNegotiator;
|
||||
|
||||
/**
|
||||
* Constructs a new FullPageVariant.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $block_storage
|
||||
* The block entity storage.
|
||||
* @param \Drupal\Core\Entity\EntityViewBuilderInterface $block_view_builder
|
||||
* The block view builder.
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The current route match.
|
||||
* @param \Drupal\Core\Theme\ThemeNegotiatorInterface $theme_negotiator
|
||||
* The theme negotiator.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $block_storage, EntityViewBuilderInterface $block_view_builder, RouteMatchInterface $route_match, ThemeNegotiatorInterface $theme_negotiator) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->blockStorage = $block_storage;
|
||||
$this->blockViewBuilder = $block_view_builder;
|
||||
$this->routeMatch = $route_match;
|
||||
$this->themeNegotiator = $theme_negotiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager')->getStorage('block'),
|
||||
$container->get('entity.manager')->getViewBuilder('block'),
|
||||
$container->get('current_route_match'),
|
||||
$container->get('theme.negotiator')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current theme for this page.
|
||||
*
|
||||
* @return string
|
||||
* The current theme.
|
||||
*/
|
||||
protected function getTheme() {
|
||||
return $this->themeNegotiator->determineActiveTheme($this->routeMatch);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
$build = array();
|
||||
// Load all region content assigned via blocks.
|
||||
foreach ($this->getRegionAssignments() as $region => $blocks) {
|
||||
/** @var $blocks \Drupal\block\BlockInterface[] */
|
||||
foreach ($blocks as $key => $block) {
|
||||
if ($block->access('view')) {
|
||||
$build[$region][$key] = $this->blockViewBuilder->view($block);
|
||||
}
|
||||
}
|
||||
if (!empty($build[$region])) {
|
||||
// self::getRegionAssignments() returns the blocks in sorted order.
|
||||
$build[$region]['#sorted'] = TRUE;
|
||||
}
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the human-readable list of regions keyed by machine name.
|
||||
*
|
||||
* @return array
|
||||
* An array of human-readable region names keyed by machine name.
|
||||
*/
|
||||
protected function getRegionNames() {
|
||||
return system_region_list($this->getTheme());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of regions and their block entities.
|
||||
*
|
||||
* @return array
|
||||
* The array is first keyed by region machine name, with the values
|
||||
* containing an array keyed by block ID, with block entities as the values.
|
||||
*/
|
||||
protected function getRegionAssignments() {
|
||||
// Build an array of the region names in the right order.
|
||||
$empty = array_fill_keys(array_keys($this->getRegionNames()), array());
|
||||
|
||||
$full = array();
|
||||
foreach ($this->blockStorage->loadByProperties(array('theme' => $this->getTheme())) as $block_id => $block) {
|
||||
$full[$block->get('region')][$block_id] = $block;
|
||||
}
|
||||
|
||||
// Merge it with the actual values to maintain the region ordering.
|
||||
$assignments = array_intersect_key(array_merge($empty, $full), $empty);
|
||||
foreach ($assignments as &$assignment) {
|
||||
// Suppress errors because PHPUnit will indirectly modify the contents,
|
||||
// triggering https://bugs.php.net/bug.php?id=50688.
|
||||
@uasort($assignment, 'Drupal\block\Entity\Block::sort');
|
||||
}
|
||||
return $assignments;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\block\Tests\Plugin\DisplayVariant\FullPageVariantTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\block\Tests\Plugin\DisplayVariant;
|
||||
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* Tests the full page display variant.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\block\Plugin\DisplayVariant\FullPageVariant
|
||||
*
|
||||
* @group Drupal
|
||||
* @group Block
|
||||
* @group Display
|
||||
*/
|
||||
class FullPageVariantTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* The block storage.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $blockStorage;
|
||||
|
||||
/**
|
||||
* The block view builder.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityViewBuilderInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $blockViewBuilder;
|
||||
|
||||
/**
|
||||
* The current route match.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\RouteMatchInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $routeMatch;
|
||||
|
||||
/**
|
||||
* The theme negotiator.
|
||||
*
|
||||
* @var \Drupal\Core\Theme\ThemeNegotiatorInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $themeNegotiator;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Full page variant test',
|
||||
'description' => '',
|
||||
'group' => 'Block',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a display variant plugin for testing.
|
||||
*
|
||||
* @param array $configuration
|
||||
* An array of plugin configuration.
|
||||
* @param array $definition
|
||||
* The plugin definition array.
|
||||
*
|
||||
* @return \Drupal\block\Plugin\DisplayVariant\FullPageVariant|\PHPUnit_Framework_MockObject_MockObject
|
||||
* A mocked display variant plugin.
|
||||
*/
|
||||
public function setUpDisplayVariant($configuration = array(), $definition = array()) {
|
||||
$this->blockStorage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
|
||||
$this->blockViewBuilder = $this->getMock('Drupal\Core\Entity\EntityViewBuilderInterface');
|
||||
$this->routeMatch = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
|
||||
$this->themeNegotiator = $this->getMock('Drupal\Core\Theme\ThemeNegotiatorInterface');
|
||||
return $this->getMockBuilder('Drupal\block\Plugin\DisplayVariant\FullPageVariant')
|
||||
->setConstructorArgs(array($configuration, 'test', $definition, $this->blockStorage, $this->blockViewBuilder, $this->routeMatch, $this->themeNegotiator))
|
||||
->setMethods(array('getRegionNames'))
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the building of a full page variant.
|
||||
*
|
||||
* @covers ::build
|
||||
* @covers ::getRegionAssignments
|
||||
*/
|
||||
public function testBuild() {
|
||||
$theme = $this->randomName();
|
||||
$display_variant = $this->setUpDisplayVariant();
|
||||
$this->themeNegotiator->expects($this->any())
|
||||
->method('determineActiveTheme')
|
||||
->with($this->routeMatch)
|
||||
->will($this->returnValue($theme));
|
||||
$display_variant->expects($this->once())
|
||||
->method('getRegionNames')
|
||||
->will($this->returnValue(array(
|
||||
'top' => 'Top',
|
||||
'bottom' => 'Bottom',
|
||||
)));
|
||||
|
||||
$blocks_config = array(
|
||||
'block1' => array(
|
||||
TRUE, 'top', 0,
|
||||
),
|
||||
// Test a block without access.
|
||||
'block2' => array(
|
||||
FALSE, 'bottom', 0,
|
||||
),
|
||||
// Test two blocks in the same region with specific weight.
|
||||
'block3' => array(
|
||||
TRUE, 'bottom', 5,
|
||||
),
|
||||
'block4' => array(
|
||||
TRUE, 'bottom', -5,
|
||||
),
|
||||
);
|
||||
$blocks = array();
|
||||
foreach ($blocks_config as $block_id => $block_config) {
|
||||
$block = $this->getMock('Drupal\block\BlockInterface');
|
||||
$block->expects($this->once())
|
||||
->method('access')
|
||||
->will($this->returnValue($block_config[0]));
|
||||
$block->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnValueMap(array(
|
||||
array('region', $block_config[1]),
|
||||
array('weight', $block_config[2]),
|
||||
array('status', TRUE),
|
||||
)));
|
||||
$blocks[$block_id] = $block;
|
||||
}
|
||||
|
||||
$this->blockViewBuilder->expects($this->exactly(3))
|
||||
->method('view')
|
||||
->will($this->returnValue(array()));
|
||||
$this->blockStorage->expects($this->once())
|
||||
->method('loadByProperties')
|
||||
->with(array('theme' => $theme))
|
||||
->will($this->returnValue($blocks));
|
||||
|
||||
$expected = array(
|
||||
'top' => array(
|
||||
'block1' => array(),
|
||||
'#sorted' => TRUE,
|
||||
),
|
||||
'bottom' => array(
|
||||
'block4' => array(),
|
||||
'block3' => array(),
|
||||
'#sorted' => TRUE,
|
||||
),
|
||||
);
|
||||
$this->assertSame($expected, $display_variant->build());
|
||||
}
|
||||
|
||||
}
|
|
@ -1324,3 +1324,25 @@
|
|||
* @see validation
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hooks
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Alter display variant plugin definitions.
|
||||
*
|
||||
* @param array $definitions
|
||||
* The array of display variant definitions, keyed by plugin ID.
|
||||
*
|
||||
* @see \Drupal\Core\Display\VariantManager
|
||||
* @see \Drupal\Core\Display\Annotation\DisplayVariant
|
||||
*/
|
||||
function hook_display_variant_plugin_alter(array &$definitions) {
|
||||
$definitions['full_page']['admin_label'] = t('Block layout');
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\Core\Display\DisplayVariantTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\Core\Display;
|
||||
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* Tests the base variant plugin.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Core\Display\VariantBase
|
||||
*
|
||||
* @group Drupal
|
||||
* @group Display
|
||||
*/
|
||||
class DisplayVariantTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Display variant',
|
||||
'description' => '',
|
||||
'group' => 'Display variant',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a display variant plugin for testing.
|
||||
*
|
||||
* @param array $configuration
|
||||
* An array of plugin configuration.
|
||||
* @param array $definition
|
||||
* The plugin definition array.
|
||||
*
|
||||
* @return \Drupal\Core\Display\VariantBase|\PHPUnit_Framework_MockObject_MockObject
|
||||
* A mocked display variant plugin.
|
||||
*/
|
||||
public function setUpDisplayVariant($configuration = array(), $definition = array()) {
|
||||
return $this->getMockBuilder('Drupal\Core\Display\VariantBase')
|
||||
->setConstructorArgs(array($configuration, 'test', $definition))
|
||||
->setMethods(array('build'))
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the label() method.
|
||||
*
|
||||
* @covers ::label
|
||||
*/
|
||||
public function testLabel() {
|
||||
$display_variant = $this->setUpDisplayVariant(array('label' => 'foo'));
|
||||
$this->assertSame('foo', $display_variant->label());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the label() method using a default value.
|
||||
*
|
||||
* @covers ::label
|
||||
*/
|
||||
public function testLabelDefault() {
|
||||
$display_variant = $this->setUpDisplayVariant();
|
||||
$this->assertSame('', $display_variant->label());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getWeight() method.
|
||||
*
|
||||
* @covers ::getWeight
|
||||
*/
|
||||
public function testGetWeight() {
|
||||
$display_variant = $this->setUpDisplayVariant(array('weight' => 5));
|
||||
$this->assertSame(5, $display_variant->getWeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getWeight() method using a default value.
|
||||
*
|
||||
* @covers ::getWeight
|
||||
*/
|
||||
public function testGetWeightDefault() {
|
||||
$display_variant = $this->setUpDisplayVariant();
|
||||
$this->assertSame(0, $display_variant->getWeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getConfiguration() method.
|
||||
*
|
||||
* @covers ::getConfiguration
|
||||
*
|
||||
* @dataProvider providerTestGetConfiguration
|
||||
*/
|
||||
public function testGetConfiguration($configuration, $expected) {
|
||||
$display_variant = $this->setUpDisplayVariant($configuration);
|
||||
|
||||
$this->assertSame($expected, $display_variant->getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test data for testGetConfiguration().
|
||||
*/
|
||||
public function providerTestGetConfiguration() {
|
||||
$data = array();
|
||||
$data[] = array(
|
||||
array(),
|
||||
array(
|
||||
'id' => 'test',
|
||||
'label' => '',
|
||||
'uuid' => '',
|
||||
'weight' => 0,
|
||||
),
|
||||
);
|
||||
$data[] = array(
|
||||
array('label' => 'Test'),
|
||||
array(
|
||||
'id' => 'test',
|
||||
'label' => 'Test',
|
||||
'uuid' => '',
|
||||
'weight' => 0,
|
||||
),
|
||||
);
|
||||
$data[] = array(
|
||||
array('id' => 'foo'),
|
||||
array(
|
||||
'id' => 'test',
|
||||
'label' => '',
|
||||
'uuid' => '',
|
||||
'weight' => 0,
|
||||
),
|
||||
);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the access() method.
|
||||
*
|
||||
* @covers ::access
|
||||
*/
|
||||
public function testAccess() {
|
||||
$display_variant = $this->setUpDisplayVariant();
|
||||
$this->assertTrue($display_variant->access());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the submitConfigurationForm() method.
|
||||
*
|
||||
* @covers ::submitConfigurationForm
|
||||
*/
|
||||
public function testSubmitConfigurationForm() {
|
||||
$display_variant = $this->setUpDisplayVariant();
|
||||
$this->assertSame('', $display_variant->label());
|
||||
|
||||
$form = array();
|
||||
$label = $this->randomName();
|
||||
$form_state['values']['label'] = $label;
|
||||
$display_variant->submitConfigurationForm($form, $form_state);
|
||||
$this->assertSame($label, $display_variant->label());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue