Unverified Commit 6eee1db2 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3032433 by tim.plunkett, neclimdul, vacho, xjm, phenaproxima: Allow...

Issue #3032433 by tim.plunkett, neclimdul, vacho, xjm, phenaproxima: Allow section storages to be loaded via routing without loading from the tempstore
parent b69a33ed
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@

use Drupal\Core\Config\Entity\ConfigEntityUpdater;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;

use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;

/**
@@ -67,3 +66,10 @@ function layout_builder_post_update_section_storage_context_mapping(&$sandbox =

  $config_entity_updater->update($sandbox, 'entity_view_display', $callback);
}

/**
 * Clear caches due to adding a new route enhancer.
 */
function layout_builder_post_update_tempstore_route_enhancer() {
  // Empty post-update hook.
}
+7 −2
Original line number Diff line number Diff line
@@ -15,9 +15,14 @@ services:
    arguments: ['@plugin.manager.layout_builder.section_storage']
    tags:
     - { name: event_subscriber }
  layout_builder.tempstore.route_enhancer:
    class: Drupal\layout_builder\Routing\LayoutTempstoreRouteEnhancer
    arguments: ['@layout_builder.tempstore_repository']
    tags:
      - { name: route_enhancer }
  layout_builder.param_converter:
    class: Drupal\layout_builder\Routing\LayoutTempstoreParamConverter
    arguments: ['@layout_builder.tempstore_repository', '@plugin.manager.layout_builder.section_storage']
    class: Drupal\layout_builder\Routing\LayoutSectionStorageParamConverter
    arguments: ['@plugin.manager.layout_builder.section_storage']
    tags:
      - { name: paramconverter, priority: 10 }
  cache_context.layout_builder_is_active:
+6 −20
Original line number Diff line number Diff line
@@ -3,24 +3,16 @@
namespace Drupal\layout_builder\Routing;

use Drupal\Core\ParamConverter\ParamConverterInterface;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface;
use Symfony\Component\Routing\Route;

/**
 * Loads the section storage from the layout tempstore.
 * Loads the section storage from the routing defaults.
 *
 * @internal
 *   Tagged services are internal.
 */
class LayoutTempstoreParamConverter implements ParamConverterInterface {

  /**
   * The layout tempstore repository.
   *
   * @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface
   */
  protected $layoutTempstoreRepository;
class LayoutSectionStorageParamConverter implements ParamConverterInterface {

  /**
   * The section storage manager.
@@ -30,15 +22,12 @@ class LayoutTempstoreParamConverter implements ParamConverterInterface {
  protected $sectionStorageManager;

  /**
   * Constructs a new LayoutTempstoreParamConverter.
   * Constructs a new LayoutSectionStorageParamConverter.
   *
   * @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository
   *   The layout tempstore repository.
   * @param \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface $section_storage_manager
   *   The section storage manager.
   */
  public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository, SectionStorageManagerInterface $section_storage_manager) {
    $this->layoutTempstoreRepository = $layout_tempstore_repository;
  public function __construct(SectionStorageManagerInterface $section_storage_manager) {
    $this->sectionStorageManager = $section_storage_manager;
  }

@@ -55,17 +44,14 @@ public function convert($value, $definition, $name, array $defaults) {
    // Load an empty instance and derive the available contexts.
    $contexts = $this->sectionStorageManager->loadEmpty($type)->deriveContextsFromRoute($value, $definition, $name, $defaults);
    // Attempt to load a full instance based on the context.
    if ($section_storage = $this->sectionStorageManager->load($type, $contexts)) {
      // Pass the plugin through the tempstore repository.
      return $this->layoutTempstoreRepository->get($section_storage);
    }
    return $this->sectionStorageManager->load($type, $contexts);
  }

  /**
   * {@inheritdoc}
   */
  public function applies($definition, $name, Route $route) {
    return !empty($definition['layout_builder_tempstore']);
    return !empty($definition['layout_builder_section_storage']) || !empty($definition['layout_builder_tempstore']);
  }

}
+44 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\layout_builder\Routing;

use Drupal\Core\Routing\EnhancerInterface;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Drupal\layout_builder\SectionStorageInterface;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Loads the section storage from the layout tempstore.
 */
class LayoutTempstoreRouteEnhancer implements EnhancerInterface {

  /**
   * The layout tempstore repository.
   *
   * @var \Drupal\layout_builder\LayoutTempstoreRepositoryInterface
   */
  protected $layoutTempstoreRepository;

  /**
   * Constructs a new LayoutTempstoreRouteEnhancer.
   *
   * @param \Drupal\layout_builder\LayoutTempstoreRepositoryInterface $layout_tempstore_repository
   *   The layout tempstore repository.
   */
  public function __construct(LayoutTempstoreRepositoryInterface $layout_tempstore_repository) {
    $this->layoutTempstoreRepository = $layout_tempstore_repository;
  }

  /**
   * {@inheritdoc}
   */
  public function enhance(array $defaults, Request $request) {
    $parameters = $defaults[RouteObjectInterface::ROUTE_OBJECT]->getOption('parameters');
    if (isset($parameters['section_storage']['layout_builder_tempstore']) && isset($defaults['section_storage']) && $defaults['section_storage'] instanceof SectionStorageInterface) {
      $defaults['section_storage'] = $this->layoutTempstoreRepository->get($defaults['section_storage']);
    }
    return $defaults;
  }

}
+7 −16
Original line number Diff line number Diff line
@@ -2,26 +2,24 @@

namespace Drupal\Tests\layout_builder\Unit;

use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Drupal\layout_builder\Routing\LayoutTempstoreParamConverter;
use Drupal\layout_builder\Routing\LayoutSectionStorageParamConverter;
use Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface;
use Drupal\layout_builder\SectionStorageInterface;
use Drupal\Tests\UnitTestCase;

/**
 * @coversDefaultClass \Drupal\layout_builder\Routing\LayoutTempstoreParamConverter
 * @coversDefaultClass \Drupal\layout_builder\Routing\LayoutSectionStorageParamConverter
 *
 * @group layout_builder
 */
class LayoutTempstoreParamConverterTest extends UnitTestCase {
class LayoutSectionStorageParamConverterTest extends UnitTestCase {

  /**
   * @covers ::convert
   */
  public function testConvert() {
    $layout_tempstore_repository = $this->prophesize(LayoutTempstoreRepositoryInterface::class);
    $section_storage_manager = $this->prophesize(SectionStorageManagerInterface::class);
    $converter = new LayoutTempstoreParamConverter($layout_tempstore_repository->reveal(), $section_storage_manager->reveal());
    $converter = new LayoutSectionStorageParamConverter($section_storage_manager->reveal());

    $section_storage = $this->prophesize(SectionStorageInterface::class);

@@ -29,26 +27,22 @@ public function testConvert() {
    $definition = ['layout_builder_tempstore' => TRUE];
    $name = 'the_parameter_name';
    $defaults = ['section_storage_type' => 'my_type'];
    $expected = 'the_return_value';

    $section_storage_manager->hasDefinition('my_type')->willReturn(TRUE);
    $section_storage_manager->loadEmpty('my_type')->willReturn($section_storage->reveal());
    $section_storage->deriveContextsFromRoute($value, $definition, $name, $defaults)->willReturn([]);
    $section_storage_manager->load('my_type', [])->willReturn($section_storage->reveal());

    $layout_tempstore_repository->get($section_storage->reveal())->willReturn($expected);

    $result = $converter->convert($value, $definition, $name, $defaults);
    $this->assertEquals($expected, $result);
    $this->assertSame($section_storage->reveal(), $result);
  }

  /**
   * @covers ::convert
   */
  public function testConvertNoType() {
    $layout_tempstore_repository = $this->prophesize(LayoutTempstoreRepositoryInterface::class);
    $section_storage_manager = $this->prophesize(SectionStorageManagerInterface::class);
    $converter = new LayoutTempstoreParamConverter($layout_tempstore_repository->reveal(), $section_storage_manager->reveal());
    $converter = new LayoutSectionStorageParamConverter($section_storage_manager->reveal());

    $value = 'some_value';
    $definition = ['layout_builder_tempstore' => TRUE];
@@ -57,7 +51,6 @@ public function testConvertNoType() {

    $section_storage_manager->hasDefinition()->shouldNotBeCalled();
    $section_storage_manager->load()->shouldNotBeCalled();
    $layout_tempstore_repository->get()->shouldNotBeCalled();

    $result = $converter->convert($value, $definition, $name, $defaults);
    $this->assertNull($result);
@@ -67,9 +60,8 @@ public function testConvertNoType() {
   * @covers ::convert
   */
  public function testConvertInvalidConverter() {
    $layout_tempstore_repository = $this->prophesize(LayoutTempstoreRepositoryInterface::class);
    $section_storage_manager = $this->prophesize(SectionStorageManagerInterface::class);
    $converter = new LayoutTempstoreParamConverter($layout_tempstore_repository->reveal(), $section_storage_manager->reveal());
    $converter = new LayoutSectionStorageParamConverter($section_storage_manager->reveal());

    $value = 'some_value';
    $definition = ['layout_builder_tempstore' => TRUE];
@@ -78,7 +70,6 @@ public function testConvertInvalidConverter() {

    $section_storage_manager->hasDefinition('invalid')->willReturn(FALSE);
    $section_storage_manager->load()->shouldNotBeCalled();
    $layout_tempstore_repository->get()->shouldNotBeCalled();

    $result = $converter->convert($value, $definition, $name, $defaults);
    $this->assertNull($result);
Loading