You are here

class Library in Layout builder library 8

Defines a class for library based layout storage.

This plugin, ultimately, requires the 'layout' context (i.e., a context that wraps a layout entity). However, that context is normally derived from another entity, which has a reference to a layout entity in its layout_selection field.

Plugin annotation


@SectionStorage(
  id = "layout_library",
  context_definitions = {
    "entity" = @ContextDefinition("entity", required = FALSE),
    "layout" = @ContextDefinition("entity:layout", required = FALSE),
    "view_mode" = @ContextDefinition("string", required = FALSE),
  },
)

Hierarchy

Expanded class hierarchy of Library

File

src/Plugin/SectionStorage/Library.php, line 39

Namespace

Drupal\layout_library\Plugin\SectionStorage
View source
class Library extends SectionStorageBase implements ContainerFactoryPluginInterface {

  /**
   * Entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Sample entity generation.
   *
   * @var \Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator
   */
  protected $sampleEntityGenerator;

  /**
   * Constructs a new Library object.
   *
   * @param array $configuration
   *   Configuration.
   * @param string $plugin_id
   *   ID.
   * @param mixed $plugin_definition
   *   Definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator $sampleEntityGenerator
   *   Sample entity generator.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager, LayoutBuilderSampleEntityGenerator $sampleEntityGenerator) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entityTypeManager;
    $this->sampleEntityGenerator = $sampleEntityGenerator;
  }

  /**
   * {@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('layout_builder.sample_entity_generator'));
  }

  /**
   * Gets the layout.
   *
   * @return \Drupal\layout_builder\SectionListInterface|\Drupal\layout_library\Entity\Layout
   *   Layout.
   */
  protected function getLayout() {
    return $this
      ->getSectionList();
  }

  /**
   * {@inheritdoc}
   */
  public function getStorageId() {
    return $this
      ->getLayout()
      ->id();
  }

  /**
   * {@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 ($layout = $this->entityTypeManager
      ->getStorage('layout')
      ->load($id)) {
      return $layout;
    }
    throw new \InvalidArgumentException(sprintf('The "%s" ID for the "%s" section storage type is invalid', $id, $this
      ->getStorageType()));
  }

  /**
   * {@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;
      }

      // Add a layout-library URL off the tail of each manage display.
      $path = $entity_route
        ->getPath() . '/layout-library/{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;
      $options['parameters']['layout']['type'] = 'entity:layout';
      $this
        ->buildLayoutRoutes($collection, $this
        ->getPluginDefinition(), $path, $defaults, $requirements, $options, $entity_type_id, 'layout');
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getRedirectUrl() {
    return Url::fromRoute('entity.layout.collection');
  }

  /**
   * {@inheritdoc}
   */
  public function getLayoutBuilderUrl($rel = 'view') {
    return Url::fromRoute("layout_builder.{$this->getStorageType()}.{$this->getLayout()->getTargetEntityType()}.{$rel}", $this
      ->getRouteParameters());
  }

  /**
   * {@inheritdoc}
   */
  protected function getRouteParameters() {
    $layout = $this
      ->getLayout();
    $route_parameters = FieldUI::getRouteBundleParameter($this->entityTypeManager
      ->getDefinition($layout
      ->getTargetEntityType()), $layout
      ->getTargetBundle());
    $route_parameters['layout'] = $this
      ->getLayout()
      ->id();
    return $route_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
        ->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);
    return $value ?: $defaults['layout'];
  }

  /**
   * {@inheritdoc}
   */
  public function getContextsDuringPreview() {
    $contexts = parent::getContextsDuringPreview();
    $display = $this
      ->getLayout();
    $entity = $this->sampleEntityGenerator
      ->get($display
      ->getTargetEntityType(), $display
      ->getTargetBundle());
    $context_label = new TranslatableMarkup('@entity being viewed', [
      '@entity' => $entity
        ->getEntityType()
        ->getLabel(),
    ]);
    $contexts['layout_builder.entity'] = EntityContext::fromEntity($entity, $context_label);
    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.
   */
  protected function extractEntityFromRoute($value, array $defaults) {
    return $this->entityTypeManager
      ->getStorage('layout')
      ->load($value ?: $defaults['layout']);
  }

  /**
   * {@inheritdoc}
   */
  public function deriveContextsFromRoute($value, $definition, $name, array $defaults) {
    $contexts = [];
    if ($entity = $this
      ->extractEntityFromRoute($value, $defaults)) {
      $contexts['layout'] = EntityContext::fromEntity($entity);
    }
    return $contexts;
  }

  /**
   * {@inheritdoc}
   */
  public function label() {
    return $this
      ->getLayout()
      ->label();
  }

  /**
   * {@inheritdoc}
   */
  public function save() {
    return $this
      ->getLayout()
      ->save();
  }

  /**
   * {@inheritdoc}
   */
  public function access($operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
    $result = AccessResult::allowed();
    return $return_as_object ? $result : $result
      ->isAllowed();
  }

  /**
   * {@inheritdoc}
   */
  public function isApplicable(RefinableCacheableDependencyInterface $cacheability) {

    // Since the 'layout' context must be marked optional, ensure that it is set
    // before proceeding.
    $is_library_enabled = FALSE;
    $values = $this
      ->getContextValues();
    if (!is_null($values['layout'])) {
      $entity = $values['layout']
        ->getTargetEntityType();
      $bundle = $values['layout']
        ->getTargetBundle();
      $view_mode = $values['view_mode'];
      $entity_view_display = $this->entityTypeManager
        ->getStorage('entity_view_display')
        ->load($entity . '.' . $bundle . '.' . $view_mode);
      if ($entity_view_display) {
        $is_library_enabled = $entity_view_display
          ->getThirdPartySetting('layout_library', 'enable');
      }
    }
    return $this
      ->getSectionList() && $is_library_enabled;
  }

  /**
   * {@inheritdoc}
   */
  public function setContext($name, ComponentContextInterface $context) {
    $value = $context
      ->getContextValue();

    // This cannot be done with constraints because the context handler does not
    // currently validate optional context definitions.
    if ($name === 'entity' && $value instanceof FieldableEntityInterface && $value
      ->hasField('layout_selection') && !$value
      ->get('layout_selection')
      ->isEmpty()) {
      $name = 'layout';
      $context = EntityContext::fromEntity($value
        ->get('layout_selection')->entity);
    }
    parent::setContext($name, $context);
  }

  /**
   * {@inheritdoc}
   */
  protected function getSectionList() {
    return $this
      ->getContextValue('layout');
  }

}

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.
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.
Library::$entityTypeManager protected property Entity type manager.
Library::$sampleEntityGenerator protected property Sample entity generation.
Library::access public function Overrides \Drupal\Core\Access\AccessibleInterface::access(). Overrides SectionStorageInterface::access
Library::buildRoutes public function Provides the routes needed for Layout Builder UI. Overrides SectionStorageInterface::buildRoutes
Library::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
Library::deriveContextsFromRoute public function Derives the available plugin contexts from route values. Overrides SectionStorageInterface::deriveContextsFromRoute
Library::extractEntityFromRoute protected function Extracts an entity from the route values.
Library::extractIdFromRoute public function Configures the plugin based on route values. Overrides SectionStorageInterface::extractIdFromRoute
Library::getContextsDuringPreview public function Gets contexts for use during preview. Overrides SectionStorageBase::getContextsDuringPreview
Library::getEntityTypes protected function Returns an array of relevant entity types.
Library::getLayout protected function Gets the layout.
Library::getLayoutBuilderUrl public function Gets the URL used to display the Layout Builder UI. Overrides SectionStorageInterface::getLayoutBuilderUrl
Library::getRedirectUrl public function Gets the URL used when redirecting away from the Layout Builder UI. Overrides SectionStorageInterface::getRedirectUrl
Library::getRouteParameters protected function
Library::getSectionList protected function Gets the section list. Overrides SectionStorageBase::getSectionList
Library::getSectionListFromId public function Derives the section list from the storage ID. Overrides SectionStorageInterface::getSectionListFromId
Library::getStorageId public function Returns an identifier for this storage. Overrides SectionStorageInterface::getStorageId
Library::isApplicable public function Determines if this section storage is applicable for the current contexts. Overrides SectionStorageInterface::isApplicable
Library::label public function Gets the label for the object using the sections. Overrides SectionStorageInterface::label
Library::save public function Saves the sections. Overrides SectionStorageInterface::save
Library::setContext public function Set a context on this plugin. Overrides ContextAwarePluginBase::setContext
Library::__construct public function Constructs a new Library object. Overrides ContextAwarePluginBase::__construct
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