Skip to content
Snippets Groups Projects
Commit a33a9bfa authored by Kristof De Jaeger's avatar Kristof De Jaeger
Browse files

Issue #2939322 by pookmish, silverham, swentel, dkosbob: Provide entity context to DS block fields

parent 12d6d716
No related branches found
No related tags found
No related merge requests found
Pipeline #68475 canceled
......@@ -10,3 +10,8 @@ services:
arguments: ['@entity_type.manager']
tags:
- { name: event_subscriber }
ds.ds_block_field_entity_context:
class: Drupal\ds\ContextProvider\DsBlockFieldEntityContext
arguments: ['@entity_type.manager']
tags:
- { name: 'context_provider' }
<?php
namespace Drupal\ds\ContextProvider;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\Core\Plugin\Context\EntityContextDefinition;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Sets the current node as a context on node routes.
*/
class DsBlockFieldEntityContext implements ContextProviderInterface {
use StringTranslationTrait;
/**
* The Entity Type Manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a new NodeRouteContext.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The Entity Type Manager.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager) {
$this->entityTypeManager = $entityTypeManager;
}
/**
* {@inheritdoc}
*/
public function getRuntimeContexts(array $unqualified_context_ids) {
// We set these values at runtime in
// \Drupal\ds\Plugin\DsField\BlockBase::build(),
// so just create empty contexts.
$result = [];
$entity_type_ids = array_keys($this->entityTypeManager->getDefinitions());
foreach ($entity_type_ids as $entity_type_id) {
$empty_entity = NULL;
$context_definition = EntityContextDefinition::create($entity_type_id)->setRequired(FALSE);
$context = new Context($context_definition, $empty_entity);
$cacheability = new CacheableMetadata();
// Not cacheable.
$cacheability->setCacheMaxAge(0);
$context->addCacheableDependency($cacheability);
$result[$entity_type_id] = $context;
}
return $result;
}
/**
* {@inheritdoc}
*/
public function getAvailableContexts() {
$contexts = [];
$entity_types = $this->entityTypeManager->getDefinitions();
foreach ($entity_types as $entity_type_id => $entity_type) {
$contexts[$entity_type_id] = EntityContext::fromEntityTypeId($entity_type_id, $this->t('@type set by DS Block Field', ['@type' => $entity_type->getLabel()]));
}
return $contexts;
}
}
......@@ -122,11 +122,11 @@ class BlockFieldForm extends FieldFormBase implements ContainerInjectionInterfac
$block_id = $this->field['properties']['block'];
$block = $manager->createInstance($block_id);
// Inject default theme in form state (Site branding needs it for instance).
// Create fake form state and inject default theme in form state (Site
// branding needs it for instance).
$fake_form_state = new FormState();
$default_theme = $this->config('system.theme')->get('default');
$fake_form_state->set('block_theme', $default_theme);
$block_config_form = $block->blockForm([], $fake_form_state);
if ($block_config_form) {
$url = Url::fromRoute('ds.manage_block_field_config', ['field_key' => $this->field['id']]);
......
......@@ -3,6 +3,8 @@
namespace Drupal\ds\Plugin\DsField;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextHandlerInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;
......@@ -81,14 +83,26 @@ abstract class BlockBase extends DsFieldBase implements ContainerFactoryPluginIn
$add_wrappers = isset($this->getFieldConfiguration()['properties']['add_block_wrappers']) && $this->getFieldConfiguration()['properties']['add_block_wrappers'];
if ($block->access(\Drupal::currentUser())) {
// Inject context values.
if ($block instanceof ContextAwarePluginInterface) {
$contexts = $this->contextRepository->getRuntimeContexts(array_values($block->getContextMapping()));
$this->contextHandler->applyContextMapping($block, $contexts);
// Inject context values.
if ($block instanceof ContextAwarePluginInterface) {
$contexts = $this->contextRepository->getRuntimeContexts(array_values($block->getContextMapping()));
// Set the configured entity now.
$entity_type_id = $this->configuration['entity']->getEntityTypeId();
if (isset($contexts["@ds.ds_block_field_entity_context:{$entity_type_id}"])) {
$contexts["@ds.ds_block_field_entity_context:{$entity_type_id}"]->getContextData()
->setValue($this->configuration['entity']);
$contexts['view_mode'] = new Context(new ContextDefinition('string'), $this->configuration['view_mode']);
}
$this->contextHandler->applyContextMapping($block, $contexts);
}
if ($block->access(\Drupal::currentUser())) {
$block_build = $block->build();
if (Element::isEmpty($block_build)) {
return [];
}
// If the user has chosen to add the block wrappers, theme as a block.
if ($add_wrappers) {
// @see \Drupal\block\BlockViewBuilder::buildPreRenderableBlock
......@@ -108,7 +122,6 @@ abstract class BlockBase extends DsFieldBase implements ContainerFactoryPluginIn
$render_element = $block_build;
}
// Merge cache contexts, tags and max-age.
if ($contexts = $block->getCacheContexts()) {
$render_element['#cache']['contexts'] = [];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment