class DefaultsSectionStorage

Same name in other branches
  1. 9 core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php \Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage
  2. 8.9.x core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php \Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage
  3. 11.x core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php \Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage

Defines the 'defaults' section storage type.

DefaultsSectionStorage uses a positive weight because:

@internal Plugin classes are internal.

Hierarchy

Expanded class hierarchy of DefaultsSectionStorage

2 files declare their use of DefaultsSectionStorage
DefaultsSectionStorageTest.php in core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php
DefaultsSectionStorageTest.php in core/modules/layout_builder/tests/src/Kernel/DefaultsSectionStorageTest.php

File

core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php, line 38

Namespace

Drupal\layout_builder\Plugin\SectionStorage
View source
class DefaultsSectionStorage extends SectionStorageBase implements ContainerFactoryPluginInterface, DefaultsSectionStorageInterface {
    
    /**
     * The entity type manager.
     *
     * @var \Drupal\Core\Entity\EntityTypeManagerInterface
     */
    protected $entityTypeManager;
    
    /**
     * The entity type bundle info.
     *
     * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
     */
    protected $entityTypeBundleInfo;
    
    /**
     * The sample entity generator.
     *
     * @var \Drupal\layout_builder\Entity\SampleEntityGeneratorInterface
     */
    protected $sampleEntityGenerator;
    
    /**
     * {@inheritdoc}
     */
    public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, SampleEntityGeneratorInterface $sample_entity_generator) {
        parent::__construct($configuration, $plugin_id, $plugin_definition);
        $this->entityTypeManager = $entity_type_manager;
        $this->entityTypeBundleInfo = $entity_type_bundle_info;
        $this->sampleEntityGenerator = $sample_entity_generator;
    }
    
    /**
     * {@inheritdoc}
     */
    public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
        return new static($configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'), $container->get('entity_type.bundle.info'), $container->get('layout_builder.sample_entity_generator'));
    }
    
    /**
     * {@inheritdoc}
     */
    protected function getSectionList() {
        return $this->getContextValue('display');
    }
    
    /**
     * Gets the entity storing the defaults.
     *
     * @return \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface
     *   The entity storing the defaults.
     */
    protected function getDisplay() {
        return $this->getSectionList();
    }
    
    /**
     * {@inheritdoc}
     */
    public function getStorageId() {
        return $this->getDisplay()
            ->id();
    }
    
    /**
     * {@inheritdoc}
     */
    public function getRedirectUrl() {
        return Url::fromRoute("entity.entity_view_display.{$this->getDisplay()->getTargetEntityTypeId()}.view_mode", $this->getRouteParameters());
    }
    
    /**
     * {@inheritdoc}
     */
    public function getLayoutBuilderUrl($rel = 'view') {
        return Url::fromRoute("layout_builder.{$this->getStorageType()}.{$this->getDisplay()->getTargetEntityTypeId()}.{$rel}", $this->getRouteParameters());
    }
    
    /**
     * Provides the route parameters needed to generate a URL for this object.
     *
     * @return mixed[]
     *   An associative array of parameter names and values.
     */
    protected function getRouteParameters() {
        $display = $this->getDisplay();
        $entity_type = $this->entityTypeManager
            ->getDefinition($display->getTargetEntityTypeId());
        $bundle_parameter_key = $entity_type->getBundleEntityType() ?: 'bundle';
        return [
            $bundle_parameter_key => $display->getTargetBundle(),
            'view_mode_name' => $display->getMode(),
        ];
    }
    
    /**
     * {@inheritdoc}
     */
    public function buildRoutes(RouteCollection $collection) {
        if (!\Drupal::moduleHandler()->moduleExists('field_ui')) {
            return;
        }
        foreach ($this->getEntityTypes() as $entity_type_id => $entity_type) {
            // Try to get the route from the current collection.
            if (!($entity_route = $collection->get($entity_type->get('field_ui_base_route')))) {
                continue;
            }
            $path = $entity_route->getPath() . '/display/{view_mode_name}/layout';
            $defaults = [];
            $defaults['entity_type_id'] = $entity_type_id;
            // If the entity type has no bundles and it doesn't use {bundle} in its
            // admin path, use the entity type.
            if (!str_contains($path, '{bundle}')) {
                if (!$entity_type->hasKey('bundle')) {
                    $defaults['bundle'] = $entity_type_id;
                }
                else {
                    $defaults['bundle_key'] = $entity_type->getBundleEntityType();
                }
            }
            $requirements = [];
            $requirements['_field_ui_view_mode_access'] = 'administer ' . $entity_type_id . ' display';
            $options = $entity_route->getOptions();
            $options['_admin_route'] = FALSE;
            $this->buildLayoutRoutes($collection, $this->getPluginDefinition(), $path, $defaults, $requirements, $options, $entity_type_id, 'entity_view_display');
            // Set field_ui.route_enhancer to run on the manage layout form.
            if (isset($defaults['bundle_key'])) {
                $collection->get("layout_builder.defaults.{$entity_type_id}.view")
                    ->setOption('_field_ui', TRUE)
                    ->setDefault('bundle', '');
            }
            $route_names = [
                "entity.entity_view_display.{$entity_type_id}.default",
                "entity.entity_view_display.{$entity_type_id}.view_mode",
            ];
            foreach ($route_names as $route_name) {
                if (!($route = $collection->get($route_name))) {
                    continue;
                }
                $route->addDefaults([
                    'section_storage_type' => $this->getStorageType(),
                    'section_storage' => '',
                ] + $defaults);
                $parameters['section_storage']['layout_builder_tempstore'] = TRUE;
                $parameters = NestedArray::mergeDeep($parameters, $route->getOption('parameters') ?: []);
                $route->setOption('parameters', $parameters);
            }
        }
    }
    
    /**
     * Returns an array of relevant entity types.
     *
     * @return \Drupal\Core\Entity\EntityTypeInterface[]
     *   An array of entity types.
     */
    protected function getEntityTypes() {
        return array_filter($this->entityTypeManager
            ->getDefinitions(), function (EntityTypeInterface $entity_type) {
            return $entity_type->entityClassImplements(FieldableEntityInterface::class) && $entity_type->hasHandlerClass('form', 'layout_builder') && $entity_type->hasViewBuilderClass() && $entity_type->get('field_ui_base_route');
        });
    }
    
    /**
     * {@inheritdoc}
     */
    public function getContextsDuringPreview() {
        $contexts = parent::getContextsDuringPreview();
        // During preview add a sample entity for the target entity type and bundle.
        $display = $this->getDisplay();
        $entity = $this->sampleEntityGenerator
            ->get($display->getTargetEntityTypeId(), $display->getTargetBundle());
        $contexts['layout_builder.entity'] = EntityContext::fromEntity($entity);
        return $contexts;
    }
    
    /**
     * {@inheritdoc}
     */
    public function deriveContextsFromRoute($value, $definition, $name, array $defaults) {
        $contexts = [];
        if ($entity = $this->extractEntityFromRoute($value, $defaults)) {
            $contexts['display'] = EntityContext::fromEntity($entity);
        }
        return $contexts;
    }
    
    /**
     * Extracts an entity from the route values.
     *
     * @param mixed $value
     *   The raw value from the route.
     * @param array $defaults
     *   The route defaults array.
     *
     * @return \Drupal\Core\Entity\EntityInterface|null
     *   The entity for the route, or NULL if none exist.
     *
     * @see \Drupal\layout_builder\SectionStorageInterface::deriveContextsFromRoute()
     * @see \Drupal\Core\ParamConverter\ParamConverterInterface::convert()
     */
    private function extractEntityFromRoute($value, array $defaults) {
        // If a bundle is not provided but a value corresponding to the bundle key
        // is, use that for the bundle value.
        if (empty($defaults['bundle']) && isset($defaults['bundle_key']) && !empty($defaults[$defaults['bundle_key']])) {
            $defaults['bundle'] = $defaults[$defaults['bundle_key']];
        }
        if (is_string($value) && str_contains($value, '.')) {
            [
                $entity_type_id,
                $bundle,
                $view_mode,
            ] = explode('.', $value, 3);
        }
        elseif (!empty($defaults['entity_type_id']) && !empty($defaults['bundle']) && !empty($defaults['view_mode_name'])) {
            $entity_type_id = $defaults['entity_type_id'];
            $bundle = $defaults['bundle'];
            $view_mode = $defaults['view_mode_name'];
            $value = "{$entity_type_id}.{$bundle}.{$view_mode}";
        }
        else {
            return NULL;
        }
        $storage = $this->entityTypeManager
            ->getStorage('entity_view_display');
        // If the display does not exist, create a new one.
        if (!($display = $storage->load($value))) {
            $display = $storage->create([
                'targetEntityType' => $entity_type_id,
                'bundle' => $bundle,
                'mode' => $view_mode,
                'status' => TRUE,
            ]);
        }
        return $display;
    }
    
    /**
     * {@inheritdoc}
     */
    public function label() {
        return $this->getDisplay()
            ->label();
    }
    
    /**
     * {@inheritdoc}
     */
    public function save() {
        return $this->getDisplay()
            ->save();
    }
    
    /**
     * {@inheritdoc}
     */
    public function isOverridable() {
        return $this->getDisplay()
            ->isOverridable();
    }
    
    /**
     * {@inheritdoc}
     */
    public function setOverridable($overridable = TRUE) {
        $this->getDisplay()
            ->setOverridable($overridable);
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function setThirdPartySetting($module, $key, $value) {
        $this->getDisplay()
            ->setThirdPartySetting($module, $key, $value);
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function isLayoutBuilderEnabled() {
        return $this->getDisplay()
            ->isLayoutBuilderEnabled();
    }
    
    /**
     * {@inheritdoc}
     */
    public function enableLayoutBuilder() {
        $this->getDisplay()
            ->enableLayoutBuilder();
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function disableLayoutBuilder() {
        $this->getDisplay()
            ->disableLayoutBuilder();
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getThirdPartySetting($module, $key, $default = NULL) {
        return $this->getDisplay()
            ->getThirdPartySetting($module, $key, $default);
    }
    
    /**
     * {@inheritdoc}
     */
    public function getThirdPartySettings($module) {
        return $this->getDisplay()
            ->getThirdPartySettings($module);
    }
    
    /**
     * {@inheritdoc}
     */
    public function unsetThirdPartySetting($module, $key) {
        $this->getDisplay()
            ->unsetThirdPartySetting($module, $key);
        return $this;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getThirdPartyProviders() {
        return $this->getDisplay()
            ->getThirdPartyProviders();
    }
    
    /**
     * {@inheritdoc}
     */
    public function access($operation, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
        $result = AccessResult::allowedIf($this->isLayoutBuilderEnabled())
            ->addCacheableDependency($this);
        return $return_as_object ? $result : $result->isAllowed();
    }
    
    /**
     * {@inheritdoc}
     */
    public function isApplicable(RefinableCacheableDependencyInterface $cacheability) {
        $cacheability->addCacheableDependency($this);
        return $this->isLayoutBuilderEnabled();
    }
    
    /**
     * {@inheritdoc}
     */
    public function setContext($name, ComponentContextInterface $context) {
        // Set the view mode context based on the display context.
        if ($name === 'display') {
            $this->setContextValue('view_mode', $context->getContextValue()
                ->getMode());
        }
        parent::setContext($name, $context);
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
ContextAwarePluginTrait::$context protected property The data objects representing the context of this plugin.
ContextAwarePluginTrait::getCacheContexts public function 10
ContextAwarePluginTrait::getCacheMaxAge public function 6
ContextAwarePluginTrait::getCacheTags public function 3
ContextAwarePluginTrait::getContext public function
ContextAwarePluginTrait::getContextDefinition public function
ContextAwarePluginTrait::getContextDefinitions public function
ContextAwarePluginTrait::getContextMapping public function 1
ContextAwarePluginTrait::getContexts public function
ContextAwarePluginTrait::getContextValue public function
ContextAwarePluginTrait::getContextValues public function
ContextAwarePluginTrait::getPluginDefinition abstract public function 1
ContextAwarePluginTrait::setContextMapping public function
ContextAwarePluginTrait::setContextValue public function
ContextAwarePluginTrait::validateContexts public function
DefaultsSectionStorage::$entityTypeBundleInfo protected property The entity type bundle info.
DefaultsSectionStorage::$entityTypeManager protected property The entity type manager.
DefaultsSectionStorage::$sampleEntityGenerator protected property The sample entity generator.
DefaultsSectionStorage::access public function Overrides \Drupal\Core\Access\AccessibleInterface::access(). Overrides SectionStorageInterface::access
DefaultsSectionStorage::buildRoutes public function Provides the routes needed for Layout Builder UI. Overrides SectionStorageInterface::buildRoutes
DefaultsSectionStorage::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
DefaultsSectionStorage::deriveContextsFromRoute public function Derives the available plugin contexts from route values. Overrides SectionStorageInterface::deriveContextsFromRoute
DefaultsSectionStorage::disableLayoutBuilder public function
DefaultsSectionStorage::enableLayoutBuilder public function
DefaultsSectionStorage::extractEntityFromRoute private function Extracts an entity from the route values.
DefaultsSectionStorage::getContextsDuringPreview public function Gets contexts for use during preview. Overrides SectionStorageBase::getContextsDuringPreview
DefaultsSectionStorage::getDisplay protected function Gets the entity storing the defaults.
DefaultsSectionStorage::getEntityTypes protected function Returns an array of relevant entity types.
DefaultsSectionStorage::getLayoutBuilderUrl public function Gets the URL used to display the Layout Builder UI. Overrides SectionStorageInterface::getLayoutBuilderUrl
DefaultsSectionStorage::getRedirectUrl public function Gets the URL used when redirecting away from the Layout Builder UI. Overrides SectionStorageInterface::getRedirectUrl
DefaultsSectionStorage::getRouteParameters protected function Provides the route parameters needed to generate a URL for this object.
DefaultsSectionStorage::getSectionList protected function Gets the section list. Overrides SectionStorageBase::getSectionList
DefaultsSectionStorage::getStorageId public function Returns an identifier for this storage. Overrides SectionStorageInterface::getStorageId
DefaultsSectionStorage::getThirdPartyProviders public function
DefaultsSectionStorage::getThirdPartySetting public function
DefaultsSectionStorage::getThirdPartySettings public function
DefaultsSectionStorage::isApplicable public function Determines if this section storage is applicable for the current contexts. Overrides SectionStorageInterface::isApplicable
DefaultsSectionStorage::isLayoutBuilderEnabled public function
DefaultsSectionStorage::isOverridable public function
DefaultsSectionStorage::label public function Gets the label for the object using the sections. Overrides SectionStorageInterface::label
DefaultsSectionStorage::save public function Saves the sections. Overrides SectionStorageInterface::save
DefaultsSectionStorage::setContext public function Overrides ContextAwarePluginTrait::setContext
DefaultsSectionStorage::setOverridable public function
DefaultsSectionStorage::setThirdPartySetting public function
DefaultsSectionStorage::unsetThirdPartySetting public function
DefaultsSectionStorage::__construct public function
LayoutBuilderRoutesTrait::buildLayoutRoutes protected function Builds the layout routes for the given values.
PluginInspectionInterface::getPluginId public function Gets the plugin ID of the plugin instance. 2
SectionStorageBase::appendSection public function Appends a new section to the end of the list. Overrides SectionListInterface::appendSection
SectionStorageBase::count public function
SectionStorageBase::getSection public function Gets a domain object for the layout section. Overrides SectionListInterface::getSection
SectionStorageBase::getSections public function Gets the layout sections. Overrides SectionListInterface::getSections 1
SectionStorageBase::getStorageType public function Returns the type of this storage. Overrides SectionStorageInterface::getStorageType
SectionStorageBase::getTempstoreKey public function Gets a string suitable for use as a tempstore key. Overrides TempStoreIdentifierInterface::getTempstoreKey 1
SectionStorageBase::insertSection public function Inserts a new section at a given delta. Overrides SectionListInterface::insertSection
SectionStorageBase::removeAllSections public function Removes all of the sections. Overrides SectionListInterface::removeAllSections
SectionStorageBase::removeSection public function Removes the section at the given delta. Overrides SectionListInterface::removeSection

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.