Commit 32ef4a82 authored by Tom Keitel's avatar Tom Keitel
Browse files

Issue #3253659 by hctom: Get rid of preview context detection when determining...

Issue #3253659 by hctom: Get rid of preview context detection when determining view mode to switch to
parent dd4e6360
Loading
Loading
Loading
Loading
+9 −31
Original line number Diff line number Diff line
@@ -2,8 +2,6 @@

namespace Drupal\view_mode_switch;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityViewModeInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
@@ -18,13 +16,6 @@ class ViewModeSwitch implements ViewModeSwitchInterface {

  use StringTranslationTrait;

  /**
   * The instantiated cache backend.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $cache;

  /**
   * The entity type manager.
   *
@@ -53,13 +44,10 @@ class ViewModeSwitch implements ViewModeSwitchInterface {
   *   The view mode switch entity field manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   A cache backend used to store view mode switches.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger
   *   The logger channel factory.
   */
  public function __construct(EntityFieldManagerInterface $view_mode_switch_field_manager, EntityTypeManagerInterface $entity_type_manager, CacheBackendInterface $cache, LoggerChannelFactoryInterface $logger) {
    $this->cache = $cache;
  public function __construct(EntityFieldManagerInterface $view_mode_switch_field_manager, EntityTypeManagerInterface $entity_type_manager, LoggerChannelFactoryInterface $logger) {
    $this->entityTypeManager = $entity_type_manager;
    $this->logger = $logger;
    $this->viewModeSwitchEntityFieldManager = $view_mode_switch_field_manager;
@@ -75,6 +63,9 @@ class ViewModeSwitch implements ViewModeSwitchInterface {
   * @see \Drupal\view_mode_switch\ViewModeSwitch::doGetViewModeToSwitchTo()
   */
  public function getViewModeToSwitchTo(FieldableEntityInterface $entity, $view_mode): ?string {
    /** @var array $cache */
    $cache = &drupal_static(__METHOD__, []);

    $entity_type_id = $entity->getEntityTypeId();
    $bundle = $entity->bundle();

@@ -86,28 +77,15 @@ class ViewModeSwitch implements ViewModeSwitchInterface {
      $view_mode,
    ]);

    // Entity is not in preview and cached data exists?
    if (($cache = $this->cache->get($cid))) {
      return !empty($cache->data) ? $cache->data : NULL;
    // Cached data exists?
    if (isset($cache[$cid])) {
      return $cache[$cid] ?: NULL;
    }

    // Determine view mode to switch to (if any).
    $switch_to_view_mode = $this->doGetViewModeToSwitchTo($entity, $view_mode) ?: FALSE;

    // Check for potential preview contexts.
    $is_preview_context = [
      // Is entity preview (e.g. node preview)?
      !empty($entity->in_preview),
      // Is paragraphs entity preview in experimental widget?
      $entity_type_id === 'paragraph' && $view_mode === 'preview',
    ];

    // Save to cache (if not in preview context).
    if (!array_filter($is_preview_context)) {
      $this->cache->set($cid, $switch_to_view_mode, Cache::PERMANENT, $entity->getCacheTags());
    }
    $cache[$cid] = $this->doGetViewModeToSwitchTo($entity, $view_mode) ?: FALSE;

    return $switch_to_view_mode ?: NULL;
    return $cache[$cid] ?: NULL;
  }

  /**
+1 −68
Original line number Diff line number Diff line
@@ -2,8 +2,6 @@

namespace Drupal\Tests\view_mode_switch\Unit;

use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityTypeManagerInterface;
@@ -25,13 +23,6 @@ use Drupal\view_mode_switch\ViewModeSwitch;
 */
class ViewModeSwitchTest extends UnitTestCase {

  /**
   * A cache backend used to store view mode switches.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $cacheBackend;

  /**
   * The entity type manager.
   *
@@ -72,7 +63,6 @@ class ViewModeSwitchTest extends UnitTestCase {
    \Drupal::setContainer($container);

    // Create required service mocks.
    $this->cacheBackend = $this->createMock(CacheBackendInterface::class);
    $this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
    $this->logger = $this->createMock(LoggerChannelFactoryInterface::class);
    $this->viewModeSwitchEntityFieldManager = $this->createMock(EntityFieldManagerInterface::class);
@@ -96,7 +86,6 @@ class ViewModeSwitchTest extends UnitTestCase {
      ->setConstructorArgs([
        $this->viewModeSwitchEntityFieldManager,
        $this->entityTypeManager,
        $this->cacheBackend,
        $this->logger,
      ])
      ->getMock();
@@ -306,45 +295,27 @@ class ViewModeSwitchTest extends UnitTestCase {
      'with-id' => [
        'entity_type_test',
        1,
        FALSE,
        'foo',
        'bar',
      ],
      'without-id' => [
        'entity_type_test',
        NULL,
        FALSE,
        'foo',
        'barbaz',
      ],
      'with-id-but-no-switch' => [
        'entity_type_test',
        2,
        FALSE,
        'foo',
        NULL,
      ],
      'with-id-in-preview-context' => [
        'entity_type_test',
        3,
        TRUE,
        'foo',
        'baz',
      ],
      'paragraph-entity' => [
        'paragraph',
        4,
        FALSE,
        'foo',
        'foobar',
      ],
      'paragraph-entity-in-preview-context' => [
        'paragraph',
        5,
        FALSE,
        'preview',
        'foobar_bar',
      ],
    ];
  }

@@ -355,9 +326,6 @@ class ViewModeSwitchTest extends UnitTestCase {
   *   The type to use for the entity ID.
   * @param int|null $entity_id
   *   A numeric entity ID or NULL to automatically use the UUID as fallback.
   * @param bool $entity_is_in_preview
   *   Whether the test entity should have the 'in_preview' property set to
   *   TRUE.
   * @param string $origin_view_mode
   *   The origin view mode to start from.
   * @param string|null $expected_target_view_mode
@@ -367,23 +335,11 @@ class ViewModeSwitchTest extends UnitTestCase {
   *
   * @dataProvider dataProviderGetViewModeToSwitchTo
   */
  public function testGetViewModeToSwitchTo(string $entity_type_id, ?int $entity_id, bool $entity_is_in_preview, string $origin_view_mode, ?string $expected_target_view_mode): void {
  public function testGetViewModeToSwitchTo(string $entity_type_id, ?int $entity_id, string $origin_view_mode, ?string $expected_target_view_mode): void {
    $bundle = 'bundle_test';
    $entity_cache_tags = [
      'entity_type_test:' . $entity_id,
      'another_cache_tag',
    ];

    // Will be cached?
    $no_cache = $entity_is_in_preview;
    if ($entity_type_id === 'paragraph' && $origin_view_mode === 'preview') {
      $no_cache = TRUE;
    }

    // Create entity mock.
    $entity = $this->createMock(FieldableEntityInterface::class);
    // @phpstan-ignore-next-line
    $entity->in_preview = $entity_is_in_preview;

    $entity->expects($this->exactly(2))
      ->method('getEntityTypeId')
@@ -397,29 +353,6 @@ class ViewModeSwitchTest extends UnitTestCase {
      ->method('id')
      ->willReturn($entity_id);

    $entity->expects($no_cache ? $this->never() : $this->once())
      ->method('getCacheTags')
      ->willReturn($entity_cache_tags);

    // Prepare cache backend mock.
    $cid = implode(':', [
      $entity_type_id,
      $bundle,
      $entity_id,
      $origin_view_mode,
    ]);

    $this->cacheBackend->expects($this->exactly(2))
      ->method('get')
      ->with($cid)
      ->willReturnOnConsecutiveCalls(NULL, (object) [
        'data' => $expected_target_view_mode,
      ]);

    $this->cacheBackend->expects($no_cache ? $this->never() : $this->once())
      ->method('set')
      ->with($cid, $expected_target_view_mode, Cache::PERMANENT, $entity_cache_tags);

    // Create and configure custom view mode switch service mock.
    $view_mode_switch = $this->setUpViewModeSwitchMock([
      'doGetViewModeToSwitchTo',
+1 −7
Original line number Diff line number Diff line
services:
  cache.view_mode_switch:
    class: Drupal\Core\Cache\CacheBackendInterface
    tags:
      - { name: cache.bin, default_backend: cache.backend.chainedfast }
    factory: cache_factory:get
    arguments: [view_mode_switch]
  view_mode_switch:
    class: Drupal\view_mode_switch\ViewModeSwitch
    arguments: ['@view_mode_switch.entity_field_manager', '@entity_type.manager', '@cache.view_mode_switch', '@logger.factory']
    arguments: ['@view_mode_switch.entity_field_manager', '@entity_type.manager', '@logger.factory']
  view_mode_switch.entity_field_manager:
    class: Drupal\view_mode_switch\Entity\EntityFieldManager
    arguments: ['@entity_field.manager', '@entity_type.manager']