Skip to content
Snippets Groups Projects
Verified Commit 4fcae3ca authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3421019 by DanielVeza, sorlov, andypost, smustgrave, larowlan,...

Issue #3421019 by DanielVeza, sorlov, andypost, smustgrave, larowlan, mstrelan, alexpott: Convert SectionStorage plugin discovery to attributes
parent bd4b8b98
Branches
Tags
29 merge requests!11131[10.4.x-only-DO-NOT-MERGE]: Issue ##2842525 Ajax attached to Views exposed filter form does not trigger callbacks,!9470[10.3.x-only-DO-NOT-MERGE]: #3331771 Fix file_get_contents(): Passing null to parameter,!8540Issue #3457061: Bootstrap Modal dialog Not closing after 10.3.0 Update,!8528Issue #3456871 by Tim Bozeman: Support NULL services,!8373Issue #3427374 by danflanagan8, Vighneshh: taxonomy_tid ViewsArgumentDefault...,!7526Expose roles in response,!7352Draft: Resolve #3203489 "Set filename as",!3878Removed unused condition head title for views,!3818Issue #2140179: $entity->original gets stale between updates,!3742Issue #3328429: Create item list field formatter for displaying ordered and unordered lists,!3731Claro: role=button on status report items,!3651Issue #3347736: Create new SDC component for Olivero (header-search),!3531Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!3355Issue #3209129: Scrolling problems when adding a block via layout builder,!3154Fixes #2987987 - CSRF token validation broken on routes with optional parameters.,!3133core/modules/system/css/components/hidden.module.css,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!2812Issue #3312049: [Followup] Fix Drupal.Commenting.FunctionComment.MissingReturnType returns for NULL,!2794Issue #3100732: Allow specifying `meta` data on JSON:API objects,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2062Issue #3246454: Add weekly granularity to views date sort,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!877Issue #2708101: Default value for link text is not saved,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493
<?php
namespace Drupal\layout_builder\Attribute;
use Drupal\Component\Plugin\Attribute\Plugin;
use Drupal\layout_builder\SectionStorage\SectionStorageDefinition;
/**
* Defines a SectionStorage attribute.
*
* Plugin Namespace: Plugin\SectionStorage
*
* @see \Drupal\layout_builder\SectionStorage\SectionStorageManager
* @see plugin_api
*/
#[\Attribute(\Attribute::TARGET_CLASS)]
class SectionStorage extends Plugin {
/**
* Constructs a SectionStorage attribute.
*
* @param string $id
* The plugin ID.
* @param int $weight
* (optional) The plugin weight.
* When an entity with layout is rendered, section storage plugins are
* checked, in order of their weight, to determine which one should be used
* to render the layout.
* @param \Drupal\Component\Plugin\Context\ContextDefinitionInterface[] $context_definitions
* (optional) Any required context definitions.
* When an entity with layout is rendered, all section storage plugins which
* match a particular set of contexts are checked, in order of their weight,
* to determine which plugin should be used to render the layout.
* @see \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface::findByContext()
* @param bool $handles_permission_check
* (optional) Indicates that this section storage handles its own
* permission checking. If FALSE, the 'configure any layout' permission
* will be required during routing access. If TRUE, Layout Builder will
* not enforce any access restrictions for the storage, so the section
* storage's implementation of access() must perform the access checking itself.
* @param string|null $deriver
* (optional) The deriver class.
*/
public function __construct(
public readonly string $id,
public readonly int $weight = 0,
public readonly array $context_definitions = [],
public readonly bool $handles_permission_check = FALSE,
public readonly ?string $deriver = NULL,
) {}
/**
* {@inheritdoc}
*/
public function get(): SectionStorageDefinition {
return new SectionStorageDefinition([
'id' => $this->id,
'class' => $this->class,
'weight' => $this->weight,
'context_definitions' => $this->context_definitions,
'handles_permission_check' => $this->handles_permission_check,
]);
}
}
......@@ -331,7 +331,7 @@ protected function buildSections(FieldableEntityInterface $entity) {
$build[$delta] = $section->toRenderArray($contexts);
}
}
// The render array is built based on decisions made by @SectionStorage
// The render array is built based on decisions made by SectionStorage
// plugins and therefore it needs to depend on the accumulated
// cacheability of those decisions.
$cacheability->applyTo($build);
......
......@@ -11,9 +11,13 @@
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\Core\Plugin\Context\EntityContextDefinition;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\layout_builder\Attribute\SectionStorage;
use Drupal\layout_builder\DefaultsSectionStorageInterface;
use Drupal\layout_builder\Entity\SampleEntityGeneratorInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -28,18 +32,20 @@
* - The default weight is 0, so other custom implementations will also take
* precedence unless otherwise specified.
*
* @SectionStorage(
* id = "defaults",
* weight = 20,
* context_definitions = {
* "display" = @ContextDefinition("entity:entity_view_display"),
* "view_mode" = @ContextDefinition("string", default_value = "default"),
* },
* )
*
* @internal
* Plugin classes are internal.
*/
#[SectionStorage(id: "defaults", weight: 20, context_definitions: [
"display" => new EntityContextDefinition(
data_type: "entity_view_display",
label: new TranslatableMarkup("Entity view display"),
),
'view_mode' => new ContextDefinition(
data_type: 'string',
label: new TranslatableMarkup("View mode"),
default_value: "default",
),
])]
class DefaultsSectionStorage extends SectionStorageBase implements ContainerFactoryPluginInterface, DefaultsSectionStorageInterface {
/**
......
......@@ -15,7 +15,9 @@
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\layout_builder\Attribute\SectionStorage;
use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay;
use Drupal\layout_builder\OverridesSectionStorageInterface;
use Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface;
......@@ -31,21 +33,28 @@
* - The default weight is 0, so custom implementations will not take
* precedence unless otherwise specified.
*
* @SectionStorage(
* id = "overrides",
* weight = -20,
* handles_permission_check = TRUE,
* context_definitions = {
* "entity" = @ContextDefinition("entity", constraints = {
* "EntityHasField" = \Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage::FIELD_NAME,
* }),
* "view_mode" = @ContextDefinition("string", default_value = "default"),
* }
* )
*
* @internal
* Plugin classes are internal.
*/
#[SectionStorage(
id: "overrides",
weight: -20,
context_definitions: [
'entity' => new ContextDefinition(
data_type: 'entity',
label: new TranslatableMarkup("Entity"),
constraints: [
"EntityHasField" => OverridesSectionStorage::FIELD_NAME,
],
),
'view_mode' => new ContextDefinition(
data_type: 'string',
label: new TranslatableMarkup("View mode"),
default_value: "default",
),
],
handles_permission_check: TRUE,
)]
class OverridesSectionStorage extends SectionStorageBase implements ContainerFactoryPluginInterface, OverridesSectionStorageInterface, SectionStorageLocalTaskProviderInterface {
/**
......
......@@ -8,7 +8,7 @@
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\Context\ContextHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\layout_builder\Annotation\SectionStorage;
use Drupal\layout_builder\Attribute\SectionStorage;
use Drupal\layout_builder\SectionStorageInterface;
/**
......@@ -43,7 +43,7 @@ class SectionStorageManager extends DefaultPluginManager implements SectionStora
* The context handler.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ContextHandlerInterface $context_handler) {
parent::__construct('Plugin/SectionStorage', $namespaces, $module_handler, SectionStorageInterface::class, SectionStorage::class);
parent::__construct('Plugin/SectionStorage', $namespaces, $module_handler, SectionStorageInterface::class, SectionStorage::class, '\Drupal\layout_builder\Annotation\SectionStorage');
$this->contextHandler = $context_handler;
......
......@@ -11,7 +11,9 @@
use Drupal\Core\Plugin\ContextAwarePluginTrait;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\layout_builder\Attribute\SectionStorage;
use Drupal\layout_builder\Plugin\SectionStorage\SectionStorageLocalTaskProviderInterface;
use Drupal\layout_builder\Routing\LayoutBuilderRoutesTrait;
use Drupal\layout_builder\Section;
......@@ -22,14 +24,13 @@
/**
* Provides section storage utilizing simple config.
*
* @SectionStorage(
* id = "test_simple_config",
* context_definitions = {
* "config_id" = @ContextDefinition("string"),
* }
* )
*/
#[SectionStorage(id: "test_simple_config", context_definitions: [
"config_id" => new ContextDefinition(
data_type: "string",
label: new TranslatableMarkup("Configuration ID"),
),
])]
class SimpleConfigSectionStorage extends PluginBase implements SectionStorageInterface, SectionStorageLocalTaskProviderInterface, ContainerFactoryPluginInterface {
use ContextAwarePluginTrait;
......
......@@ -4,6 +4,7 @@
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\layout_builder\Attribute\SectionStorage;
use Drupal\layout_builder\Plugin\SectionStorage\SectionStorageBase;
use Drupal\layout_builder\Section;
use Drupal\layout_builder\SectionComponent;
......@@ -11,11 +12,8 @@
/**
* Provides a test section storage that is controlled by state.
*
* @SectionStorage(
* id = "layout_builder_test_state",
* )
*/
#[SectionStorage(id: "layout_builder_test_state")]
class TestStateBasedSectionStorage extends SectionStorageBase {
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment