You are here

final class LayoutBuilder in Layout Builder Symmetric Translations 8

Extended LayoutBuilder element to remove actions for translations.

Hierarchy

Expanded class hierarchy of LayoutBuilder

1 file declares its use of LayoutBuilder
ElementManager.php in src/ElementManager.php

File

src/Element/LayoutBuilder.php, line 21

Namespace

Drupal\layout_builder_st\Element
View source
final class LayoutBuilder extends CoreLayoutbuilder {
  use TranslationsHelperTrait;

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

  /**
   * Constructs a new LayoutBuilder.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin ID for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository
   *   The layout tempstore repository.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   (optional) The entity type manager.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, LayoutTempstoreRepositoryInterface $layout_tempstore_repository, MessengerInterface $messenger, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $layout_tempstore_repository, $messenger);
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('layout_builder.tempstore_repository'), $container
      ->get('messenger'), $container
      ->get('entity_type.manager'));
  }

  /**
   * {@inheritdoc}
   */
  protected function buildAddSectionLink(SectionStorageInterface $section_storage, $delta) {
    $link = parent::buildAddSectionLink($section_storage, $delta);
    $this
      ->setTranslationAcess($link, $section_storage);
    return $link;
  }

  /**
   * {@inheritdoc}
   */
  protected function buildAdministrativeSection(SectionStorageInterface $section_storage, $delta) {
    $section_build = parent::buildAdministrativeSection($section_storage, $delta);
    $this
      ->setTranslationAcess($section_build['remove'], $section_storage);
    $this
      ->setTranslationAcess($section_build['configure'], $section_storage);
    if (static::isTranslation($section_storage)) {
      foreach (Element::children($section_build['layout-builder__section']) as $region) {
        $region_build =& $section_build['layout-builder__section'][$region];
        $this
          ->setTranslationAcess($region_build['layout_builder_add_block'], $section_storage);
        foreach (Element::children($region_build) as $uuid) {
          if (substr_count($uuid, '-') !== 4) {
            continue;
          }

          // Remove class that enables drag and drop.
          // @todo Can we remove drag and drop in JS?
          if (($key = array_search('js-layout-builder-block', $region_build[$uuid]['#attributes']['class'])) !== FALSE) {
            unset($region_build[$uuid]['#attributes']['class'][$key]);
          }
          if ($contextual_link_element = $this
            ->createContextualLinkElement($section_storage, $delta, $region, $uuid)) {
            $region_build[$uuid]['#contextual_links'] = $contextual_link_element;
          }
          else {
            unset($region_build[$uuid]['#contextual_links']);
          }
        }
      }
    }
    return $section_build;
  }

  /**
   * Set the #access property based section storage translation.
   */
  private function setTranslationAcess(array &$build, SectionStorageInterface $section_storage) {
    $build['#access'] = !static::isTranslation($section_storage);
  }

  /**
   * Creates contextual link element for a component.
   *
   * @param \Drupal\layout_builder\SectionStorageInterface $section_storage
   *   The section storage.
   * @param $delta
   *   The section delta.
   * @param $region
   *   The region.
   * @param $uuid
   *   The UUID of the component.
   * @param $is_translation
   *   Whether the section storage is handling a translation.
   *
   * @return array|null
   *   The contextual link render array or NULL if none.
   *
   */
  private function createContextualLinkElement(SectionStorageInterface $section_storage, $delta, $region, $uuid) {
    $section = $section_storage
      ->getSection($delta);
    $contextual_link_settings = [
      'route_parameters' => [
        'section_storage_type' => $section_storage
          ->getStorageType(),
        'section_storage' => $section_storage
          ->getStorageId(),
        'delta' => $delta,
        'region' => $region,
        'uuid' => $uuid,
      ],
    ];
    if (static::isTranslation($section_storage)) {
      $contextual_group = 'layout_builder_block_translation';
      $component = $section
        ->getComponent($uuid);

      /** @var \Drupal\Core\Language\LanguageInterface $language */
      $language = $section_storage
        ->getTranslationLanguage();
      $contextual_link_settings['route_parameters']['langcode'] = $language
        ->getId();

      /** @var \Drupal\layout_builder\Plugin\Block\InlineBlock $plugin */
      $plugin = $component
        ->getPlugin();
      if ($plugin instanceof DerivativeInspectionInterface && $plugin
        ->getBaseId() === 'inline_block') {
        $configuration = $plugin
          ->getConfiguration();

        /** @var \Drupal\block_content\Entity\BlockContent $block */
        $block = $this->entityTypeManager
          ->getStorage('block_content')
          ->loadRevision($configuration['block_revision_id']);
        if ($block
          ->isTranslatable()) {
          $contextual_group = 'layout_builder_inline_block_translation';
        }
      }
    }
    else {
      $contextual_group = 'layout_builder_block';

      // Add metadata about the current operations available in
      // contextual links. This will invalidate the client-side cache of
      // links that were cached before the 'move' link was added.
      // @see layout_builder.links.contextual.yml
      $contextual_link_settings['metadata'] = [
        'operations' => 'move:update:remove',
      ];
    }
    return [
      $contextual_group => $contextual_link_settings,
    ];
  }

  /**
   * Determines whether the component has translatable configuration.
   *
   * This function is replacement for \Drupal\layout_builder\SectionComponent::hasTranslatableConfiguration()
   * in https://www.drupal.org/project/drupal/issues/2946333#comment-13129737
   * This avoids having to alter the class in the module.
   *
   * @param \Drupal\layout_builder\SectionComponent $component
   *
   * @return bool
   *   TRUE if the plugin has translatable configuration.
   */
  private static function hasTranslatableConfiguration(SectionComponent $component) {
    $plugin = $component
      ->getPlugin();
    if ($plugin instanceof LayoutBuilderTranslatablePluginInterface) {
      return $plugin
        ->hasTranslatableConfiguration();
    }
    elseif ($plugin instanceof ConfigurableInterface) {

      // For all plugins that do not implement
      // LayoutBuilderTranslatablePluginInterface only allow label translation.
      $configuration = $plugin
        ->getConfiguration();
      return !empty($configuration['label_display']) && !empty($configuration['label']);
    }
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AjaxHelperTrait::getRequestWrapperFormat protected function Gets the wrapper format of the current request.
AjaxHelperTrait::isAjax protected function Determines if the current request is via AJAX.
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
LayoutBuilder::$entityTypeManager protected property The entity type manager.
LayoutBuilder::$layoutTempstoreRepository protected property The layout tempstore repository.
LayoutBuilder::$messenger protected property The messenger service. Overrides MessengerTrait::$messenger
LayoutBuilder::buildAddSectionLink protected function Builds a link to add a new section at a given delta. Overrides LayoutBuilder::buildAddSectionLink
LayoutBuilder::buildAdministrativeSection protected function Builds the render array for the layout section while editing. Overrides LayoutBuilder::buildAdministrativeSection
LayoutBuilder::create public static function Creates an instance of the plugin. Overrides LayoutBuilder::create
LayoutBuilder::createContextualLinkElement private function Creates contextual link element for a component.
LayoutBuilder::getInfo public function Returns the element properties for this element. Overrides ElementInterface::getInfo
LayoutBuilder::hasTranslatableConfiguration private static function Determines whether the component has translatable configuration.
LayoutBuilder::layout protected function Renders the Layout UI.
LayoutBuilder::prepareLayout protected function Prepares a layout for use in the UI.
LayoutBuilder::preRender public function Pre-render callback: Renders the Layout Builder UI.
LayoutBuilder::setTranslationAcess private function Set the #access property based section storage translation.
LayoutBuilder::__construct public function Constructs a new LayoutBuilder. Overrides LayoutBuilder::__construct
LayoutBuilderContextTrait::$contextRepository protected property The context repository.
LayoutBuilderContextTrait::contextRepository protected function Gets the context repository service.
LayoutBuilderContextTrait::getAvailableContexts protected function Provides all available contexts, both global and section_storage-specific.
LayoutBuilderHighlightTrait::blockAddHighlightId protected function Provides the ID used to highlight the active Layout Builder UI element.
LayoutBuilderHighlightTrait::blockUpdateHighlightId protected function Provides the ID used to highlight the active Layout Builder UI element.
LayoutBuilderHighlightTrait::sectionAddHighlightId protected function Provides the ID used to highlight the active Layout Builder UI element.
LayoutBuilderHighlightTrait::sectionUpdateHighlightId protected function Provides the ID used to highlight the active Layout Builder UI element.
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
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.
RenderElement::preRenderAjaxForm public static function Adds Ajax information about an element to communicate with JavaScript.
RenderElement::preRenderGroup public static function Adds members of this group as actual elements for rendering.
RenderElement::processAjaxForm public static function Form element processing handler for the #ajax form property. 1
RenderElement::processGroup public static function Arranges elements into groups.
RenderElement::setAttributes public static function Sets a form element's class attribute. Overrides ElementInterface::setAttributes
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.
TranslationsHelperTrait::isTranslation protected static function Determines if the sections is for a translation.