You are here

class DefaultsSectionStorage in Drupal 8

Same name and namespace in other branches
  1. 9 core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php \Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage
  2. 10 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:

@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.

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 44

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());
    $route_parameters = FieldUI::getRouteBundleParameter($entity_type, $display
      ->getTargetBundle());
    $route_parameters['view_mode_name'] = $display
      ->getMode();
    return $route_parameters;
  }

  /**
   * {@inheritdoc}
   */
  public function buildRoutes(RouteCollection $collection) {
    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 (strpos($path, '{bundle}') === FALSE) {
        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 extractIdFromRoute($value, $definition, $name, array $defaults) {
    @trigger_error('\\Drupal\\layout_builder\\SectionStorageInterface::extractIdFromRoute() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. \\Drupal\\layout_builder\\SectionStorageInterface::deriveContextsFromRoute() should be used instead. See https://www.drupal.org/node/3016262.', E_USER_DEPRECATED);
    if (is_string($value) && strpos($value, '.') !== FALSE) {
      return $value;
    }

    // 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 (!empty($defaults['entity_type_id']) && !empty($defaults['bundle']) && !empty($defaults['view_mode_name'])) {
      return $defaults['entity_type_id'] . '.' . $defaults['bundle'] . '.' . $defaults['view_mode_name'];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getSectionListFromId($id) {
    @trigger_error('\\Drupal\\layout_builder\\SectionStorageInterface::getSectionListFromId() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. The section list should be derived from context. See https://www.drupal.org/node/3016262.', E_USER_DEPRECATED);
    if (strpos($id, '.') === FALSE) {
      throw new \InvalidArgumentException(sprintf('The "%s" ID for the "%s" section storage type is invalid', $id, $this
        ->getStorageType()));
    }
    $storage = $this->entityTypeManager
      ->getStorage('entity_view_display');

    // If the display does not exist, create a new one.
    if (!($display = $storage
      ->load($id))) {
      list($entity_type_id, $bundle, $view_mode) = explode('.', $id, 3);
      $display = $storage
        ->create([
        'targetEntityType' => $entity_type_id,
        'bundle' => $bundle,
        'mode' => $view_mode,
        'status' => TRUE,
      ]);
    }
    return $display;
  }

  /**
   * {@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) && strpos($value, '.') !== FALSE) {
      list($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

Namesort descending Modifiers Type Description Overrides
ContextAwarePluginBase::$context protected property The data objects representing the context of this plugin.
ContextAwarePluginBase::$contexts Deprecated private property Data objects representing the contexts passed in the plugin configuration.
ContextAwarePluginBase::contextHandler protected function Wraps the context handler.
ContextAwarePluginBase::createContextFromConfiguration protected function Overrides ContextAwarePluginBase::createContextFromConfiguration
ContextAwarePluginBase::getCacheContexts public function The cache contexts associated with this object. Overrides CacheableDependencyInterface::getCacheContexts 9
ContextAwarePluginBase::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyInterface::getCacheMaxAge 7
ContextAwarePluginBase::getCacheTags public function The cache tags associated with this object. Overrides CacheableDependencyInterface::getCacheTags 4
ContextAwarePluginBase::getContext public function This code is identical to the Component in order to pick up a different Context class. Overrides ContextAwarePluginBase::getContext
ContextAwarePluginBase::getContextDefinition public function Overrides ContextAwarePluginBase::getContextDefinition
ContextAwarePluginBase::getContextDefinitions public function Overrides ContextAwarePluginBase::getContextDefinitions
ContextAwarePluginBase::getContextMapping public function Gets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface::getContextMapping
ContextAwarePluginBase::getContexts public function Gets the defined contexts. Overrides ContextAwarePluginInterface::getContexts
ContextAwarePluginBase::getContextValue public function Gets the value for a defined context. Overrides ContextAwarePluginInterface::getContextValue
ContextAwarePluginBase::getContextValues public function Gets the values for all defined contexts. Overrides ContextAwarePluginInterface::getContextValues
ContextAwarePluginBase::setContextMapping public function Sets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface::setContextMapping
ContextAwarePluginBase::setContextValue public function Sets the value for a defined context. Overrides ContextAwarePluginBase::setContextValue
ContextAwarePluginBase::validateContexts public function Validates the set values for the defined contexts. Overrides ContextAwarePluginInterface::validateContexts
ContextAwarePluginBase::__get public function Implements magic __get() method.
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 Disables the Layout Builder. Overrides LayoutBuilderEnabledInterface::disableLayoutBuilder
DefaultsSectionStorage::enableLayoutBuilder public function Enables the Layout Builder. Overrides LayoutBuilderEnabledInterface::enableLayoutBuilder
DefaultsSectionStorage::extractEntityFromRoute private function Extracts an entity from the route values.
DefaultsSectionStorage::extractIdFromRoute public function Configures the plugin based on route values. Overrides SectionStorageInterface::extractIdFromRoute
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::getSectionListFromId public function Derives the section list from the storage ID. Overrides SectionStorageInterface::getSectionListFromId
DefaultsSectionStorage::getStorageId public function Returns an identifier for this storage. Overrides SectionStorageInterface::getStorageId
DefaultsSectionStorage::getThirdPartyProviders public function Gets the list of third parties that store information. Overrides ThirdPartySettingsInterface::getThirdPartyProviders
DefaultsSectionStorage::getThirdPartySetting public function Gets the value of a third-party setting. Overrides ThirdPartySettingsInterface::getThirdPartySetting
DefaultsSectionStorage::getThirdPartySettings public function Gets all third-party settings of a given module. Overrides ThirdPartySettingsInterface::getThirdPartySettings
DefaultsSectionStorage::isApplicable public function Determines if this section storage is applicable for the current contexts. Overrides SectionStorageInterface::isApplicable
DefaultsSectionStorage::isLayoutBuilderEnabled public function Determines if Layout Builder is enabled. Overrides LayoutBuilderEnabledInterface::isLayoutBuilderEnabled
DefaultsSectionStorage::isOverridable public function Determines if the defaults allow custom overrides. Overrides DefaultsSectionStorageInterface::isOverridable
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 Set a context on this plugin. Overrides ContextAwarePluginBase::setContext
DefaultsSectionStorage::setOverridable public function Sets the defaults to allow or disallow overrides. Overrides DefaultsSectionStorageInterface::setOverridable
DefaultsSectionStorage::setThirdPartySetting public function Sets the value of a third-party setting. Overrides ThirdPartySettingsInterface::setThirdPartySetting
DefaultsSectionStorage::unsetThirdPartySetting public function Unsets a third-party setting. Overrides ThirdPartySettingsInterface::unsetThirdPartySetting
DefaultsSectionStorage::__construct public function Overrides \Drupal\Component\Plugin\PluginBase::__construct(). Overrides ContextAwarePluginBase::__construct
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
LayoutBuilderRoutesTrait::buildLayoutRoutes protected function Builds the layout routes for the given values.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
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
SectionStorageBase::setSectionList Deprecated public function Sets the section list on the storage.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
TypedDataTrait::$typedDataManager protected property The typed data manager used for creating the data types.
TypedDataTrait::getTypedDataManager public function Gets the typed data manager. 2
TypedDataTrait::setTypedDataManager public function Sets the typed data manager. 2