From 17de81c58096292bf1639b79eef55c31bfd1fd46 Mon Sep 17 00:00:00 2001
From: Francesco Placella <plach@183211.no-reply.drupal.org>
Date: Wed, 6 Mar 2019 23:46:19 +0100
Subject: [PATCH] Issue #2942675 by tim.plunkett, Sam152, plach, phenaproxima:
 Layout builder should use the active variant of an entity

---
 .../OverridesSectionStorage.php               | 18 +++++++---
 .../src/Functional/LayoutBuilderTest.php      | 33 +++++++++++++++++++
 .../Kernel/OverridesSectionStorageTest.php    |  4 +++
 .../src/Unit/OverridesSectionStorageTest.php  | 30 +++++++++--------
 4 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php
index 44c27b022d47..bd9c8690e1a5 100644
--- a/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php
+++ b/core/modules/layout_builder/src/Plugin/SectionStorage/OverridesSectionStorage.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
 use Drupal\Core\Entity\EntityFieldManagerInterface;
+use Drupal\Core\Entity\EntityRepositoryInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
@@ -74,15 +75,23 @@ class OverridesSectionStorage extends SectionStorageBase implements ContainerFac
    */
   protected $sectionStorageManager;
 
+  /**
+   * The entity repository.
+   *
+   * @var \Drupal\Core\Entity\EntityRepositoryInterface
+   */
+  protected $entityRepository;
+
   /**
    * {@inheritdoc}
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, SectionStorageManagerInterface $section_storage_manager) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, SectionStorageManagerInterface $section_storage_manager, EntityRepositoryInterface $entity_repository) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
 
     $this->entityTypeManager = $entity_type_manager;
     $this->entityFieldManager = $entity_field_manager;
     $this->sectionStorageManager = $section_storage_manager;
+    $this->entityRepository = $entity_repository;
   }
 
   /**
@@ -95,7 +104,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $plugin_definition,
       $container->get('entity_type.manager'),
       $container->get('entity_field.manager'),
-      $container->get('plugin.manager.layout_builder.section_storage')
+      $container->get('plugin.manager.layout_builder.section_storage'),
+      $container->get('entity.repository')
     );
   }
 
@@ -163,7 +173,7 @@ 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) {
       list($entity_type_id, $entity_id) = explode('.', $id, 2);
-      $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($entity_id);
+      $entity = $this->entityRepository->getActive($entity_type_id, $entity_id);
       if ($entity instanceof FieldableEntityInterface && $entity->hasField(static::FIELD_NAME)) {
         return $entity->get(static::FIELD_NAME);
       }
@@ -216,7 +226,7 @@ private function extractEntityFromRoute($value, array $defaults) {
       return NULL;
     }
 
-    $entity = $this->entityTypeManager->getStorage($entity_type_id)->load($entity_id);
+    $entity = $this->entityRepository->getActive($entity_type_id, $entity_id);
     if ($entity instanceof FieldableEntityInterface && $entity->hasField(static::FIELD_NAME)) {
       return $entity;
     }
diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
index e905346e80a5..5b41c3fcfca9 100644
--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
+++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php
@@ -630,6 +630,39 @@ public function testExtraFields() {
     $assert_session->linkExists('Read more');
   }
 
+  /**
+   * Tests loading a pending revision in the Layout Builder UI.
+   */
+  public function testPendingRevision() {
+    $assert_session = $this->assertSession();
+    $page = $this->getSession()->getPage();
+
+    $this->drupalLogin($this->drupalCreateUser([
+      'configure any layout',
+      'administer node display',
+    ]));
+
+    $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field';
+    // Enable overrides.
+    $this->drupalPostForm("$field_ui_prefix/display/default", ['layout[enabled]' => TRUE], 'Save');
+    $this->drupalPostForm("$field_ui_prefix/display/default", ['layout[allow_custom]' => TRUE], 'Save');
+
+    $storage = $this->container->get('entity_type.manager')->getStorage('node');
+    $node = $storage->load(1);
+    // Create a pending revision.
+    $pending_revision = $storage->createRevision($node, FALSE);
+    $pending_revision->set('title', 'The pending title of the first node');
+    $pending_revision->save();
+
+    // The original node title is available when viewing the node, but the
+    // pending title is visible within the Layout Builder UI.
+    $this->drupalGet('node/1');
+    $assert_session->pageTextContains('The first node title');
+    $page->clickLink('Layout');
+    $assert_session->pageTextNotContains('The first node title');
+    $assert_session->pageTextContains('The pending title of the first node');
+  }
+
   /**
    * Tests that deleting a View block used in Layout Builder works.
    */
diff --git a/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php b/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php
index 727e8632b2ae..94af274cbe9e 100644
--- a/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php
+++ b/core/modules/layout_builder/tests/src/Kernel/OverridesSectionStorageTest.php
@@ -13,6 +13,7 @@
 use Drupal\layout_builder\Section;
 use Drupal\layout_builder\SectionComponent;
 use Drupal\layout_builder\SectionListInterface;
+use Drupal\Tests\user\Traits\UserCreationTrait;
 
 /**
  * @coversDefaultClass \Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage
@@ -21,6 +22,8 @@
  */
 class OverridesSectionStorageTest extends KernelTestBase {
 
+  use UserCreationTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -46,6 +49,7 @@ class OverridesSectionStorageTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
 
+    $this->setUpCurrentUser();
     $this->installSchema('system', ['key_value_expire']);
     $this->installEntitySchema('entity_test');
 
diff --git a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
index af2ae0d12ea3..6f4b4783fdf8 100644
--- a/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/OverridesSectionStorageTest.php
@@ -3,7 +3,7 @@
 namespace Drupal\Tests\layout_builder\Unit;
 
 use Drupal\Core\Entity\EntityFieldManagerInterface;
-use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\EntityRepositoryInterface;
 use Drupal\Core\Entity\EntityType;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -45,6 +45,13 @@ class OverridesSectionStorageTest extends UnitTestCase {
    */
   protected $entityFieldManager;
 
+  /**
+   * The entity repository.
+   *
+   * @var \Drupal\Core\Entity\EntityRepositoryInterface
+   */
+  protected $entityRepository;
+
   /**
    * {@inheritdoc}
    */
@@ -54,12 +61,13 @@ protected function setUp() {
     $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
     $this->entityFieldManager = $this->prophesize(EntityFieldManagerInterface::class);
     $section_storage_manager = $this->prophesize(SectionStorageManagerInterface::class);
+    $this->entityRepository = $this->prophesize(EntityRepositoryInterface::class);
 
     $definition = new SectionStorageDefinition([
       'id' => 'overrides',
       'class' => OverridesSectionStorage::class,
     ]);
-    $this->plugin = new OverridesSectionStorage([], 'overrides', $definition, $this->entityTypeManager->reveal(), $this->entityFieldManager->reveal(), $section_storage_manager->reveal());
+    $this->plugin = new OverridesSectionStorage([], 'overrides', $definition, $this->entityTypeManager->reveal(), $this->entityFieldManager->reveal(), $section_storage_manager->reveal(), $this->entityRepository->reveal());
   }
 
   /**
@@ -120,19 +128,15 @@ public function testGetSectionListFromId($success, $expected_entity_type_id, $id
     $defaults['the_parameter_name'] = $id;
 
     if ($expected_entity_type_id) {
-      $entity_storage = $this->prophesize(EntityStorageInterface::class);
-
       $entity_without_layout = $this->prophesize(FieldableEntityInterface::class);
       $entity_without_layout->hasField(OverridesSectionStorage::FIELD_NAME)->willReturn(FALSE);
       $entity_without_layout->get(OverridesSectionStorage::FIELD_NAME)->shouldNotBeCalled();
-      $entity_storage->load('entity_without_layout')->willReturn($entity_without_layout->reveal());
+      $this->entityRepository->getActive('my_entity_type', 'entity_without_layout')->willReturn($entity_without_layout->reveal());
 
       $entity_with_layout = $this->prophesize(FieldableEntityInterface::class);
       $entity_with_layout->hasField(OverridesSectionStorage::FIELD_NAME)->willReturn(TRUE);
       $entity_with_layout->get(OverridesSectionStorage::FIELD_NAME)->willReturn('the_return_value');
-      $entity_storage->load('entity_with_layout')->willReturn($entity_with_layout->reveal());
-
-      $this->entityTypeManager->getStorage($expected_entity_type_id)->willReturn($entity_storage->reveal());
+      $this->entityRepository->getActive('my_entity_type', 'entity_with_layout')->willReturn($entity_with_layout->reveal());
 
       $entity_type = new EntityType(['id' => $expected_entity_type_id]);
       $this->entityTypeManager->getDefinition($expected_entity_type_id)->willReturn($entity_type);
@@ -191,23 +195,21 @@ public function providerTestGetSectionListFromId() {
    */
   public function testExtractEntityFromRoute($success, $expected_entity_type_id, $value, array $defaults) {
     if ($expected_entity_type_id) {
-      $entity_storage = $this->prophesize(EntityStorageInterface::class);
-
       $entity_without_layout = $this->prophesize(FieldableEntityInterface::class);
       $entity_without_layout->hasField(OverridesSectionStorage::FIELD_NAME)->willReturn(FALSE);
-      $entity_storage->load('entity_without_layout')->willReturn($entity_without_layout->reveal());
+      $this->entityRepository->getActive($expected_entity_type_id, 'entity_without_layout')->willReturn($entity_without_layout->reveal());
 
       $entity_with_layout = $this->prophesize(FieldableEntityInterface::class);
       $entity_with_layout->hasField(OverridesSectionStorage::FIELD_NAME)->willReturn(TRUE);
-      $entity_storage->load('entity_with_layout')->willReturn($entity_with_layout->reveal());
-      $this->entityTypeManager->getStorage($expected_entity_type_id)->willReturn($entity_storage->reveal());
+      $this->entityRepository->getActive($expected_entity_type_id, 'entity_with_layout')->willReturn($entity_with_layout->reveal());
+
       $entity_type = new EntityType([
         'id' => $expected_entity_type_id,
       ]);
       $this->entityTypeManager->getDefinition($expected_entity_type_id)->willReturn($entity_type);
     }
     else {
-      $this->entityTypeManager->getStorage(Argument::any())->shouldNotBeCalled();
+      $this->entityRepository->getActive(Argument::any())->shouldNotBeCalled();
     }
 
     $method = new \ReflectionMethod($this->plugin, 'extractEntityFromRoute');
-- 
GitLab