Verified Commit 9839653e authored by Dave Long's avatar Dave Long
Browse files

fix: #3468180 Undefined array key "view_mode" in block_content_theme_suggestions_block_alter

By: smustgrave
By: catch
By: sonfd
By: tobiasb
By: nicxvan
By: larowlan
By: acbramley
By: nod_
By: john.oltman
parent b7801031
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ function block_content_theme_suggestions_block_alter(array &$suggestions, array

  if ($block_content instanceof BlockContentInterface) {
    $bundle = $content['#block_content']->bundle();
    $view_mode = strtr($variables['elements']['#configuration']['view_mode'], '.', '_');
    $view_mode = strtr($variables['elements']['content']['#view_mode'], '.', '_');

    $suggestions_new[] = 'block__block_content__view__' . $view_mode;
    $suggestions_new[] = 'block__block_content__type__' . $bundle;
+5 −0
Original line number Diff line number Diff line
name: 'Block Content Theme Suggestions Test'
type: module
description: 'Support module for testing.'
package: Testing
version: VERSION
+65 −0
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Support module for testing.
 */

declare(strict_types=1);

use Drupal\block_content\BlockContentInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;

/**
 * Implements hook_theme().
 */
function block_content_theme_suggestions_test_theme(): array {
  // It is necessary to explicitly register the template via hook_theme()
  // because it is added via a module, not a theme.
  return [
    'block__block_content__view_type__basic__full' => [
      'base hook' => 'block',
    ],
  ];
}

/**
 * Implements hook_preprocess_block().
 */
function block_content_theme_suggestions_test_preprocess_block(&$variables): void {
  $block_content = $variables['elements']['content']['#block_content'] ?? NULL;
  if ($block_content instanceof BlockContentInterface) {
    $variables['label'] = $block_content->label();
  }
}

/**
 * Implements hook_node_view().
 */
function block_content_theme_suggestions_test_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, string $view_mode): void {
  // Provide content for the extra field in the form of a content block.
  if ($display->getComponent('block_content_extra_field_test')) {
    $entity_type_manager = \Drupal::entityTypeManager();
    // Load a block content entity with a known UUID created by test setup.
    // @see \Drupal\Tests\block_content\Functional\BlockContentThemeSuggestionsTest::setUp()
    $block_content = $entity_type_manager->getStorage('block_content')->loadByProperties([
      'uuid' => 'b22c881a-bcfd-4d0c-a41d-3573327705df',
    ]);
    $block_content = reset($block_content);
    $build['block_content_extra_field_test'] = $entity_type_manager->getViewBuilder('block_content')->view($block_content);
  }
}

/**
 * Implements hook_entity_extra_field_info().
 */
function block_content_theme_suggestions_test_entity_extra_field_info(): array {
  // Add an extra field to the test bundle.
  $extra['node']['bundle_with_extra_field']['display']['block_content_extra_field_test'] = [
    'label' => t('Extra field'),
    'description' => t('Extra field description'),
    'weight' => 0,
  ];
  return $extra;
}
+3 −0
Original line number Diff line number Diff line
{{ label }}

<h1>I am a block content template for a specific bundle and view mode!</h1>
+92 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\block_content\Functional;

/**
 * Tests block content theme suggestions.
 *
 * @group block_content
 */
class BlockContentThemeSuggestionsTest extends BlockContentTestBase {

  /**
   * Path prefix for the field UI for the test bundle.
   *
   * @var string
   */
  const FIELD_UI_PREFIX = 'admin/structure/types/manage/bundle_with_extra_field';

  /**
   * The UUID for a block content entity.
   */
  protected string $uuid = 'b22c881a-bcfd-4d0c-a41d-3573327705df';

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'field_ui',
    'layout_builder',
    'node',
    'block_content_theme_suggestions_test',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    // Create a block with a known UUID.
    $block = $this->createBlockContent('Example block!', 'basic', FALSE);
    $block->set('uuid', $this->uuid);
    $block->save();
  }

  /**
   * Test suggestions for content blocks.
   */
  public function testBlockContentThemeSuggestionsContent(): void {
    $this->drupalLogin($this->adminUser);
    $this->drupalPlaceBlock('block_content:' . $this->uuid);
    $this->drupalGet('');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('Example block!');
    $this->assertSession()->pageTextContainsOnce('I am a block content template for a specific bundle and view mode!');
  }

  /**
   * Test suggestions for content blocks within extra fields blocks.
   */
  public function testBlockContentThemeSuggestionsExtraField(): void {
    // Extra field blocks are a block plugin provided by layout builder, so
    // enable layouts for the test bundle and view a node of that bundle.
    // A test module injects an extra field referencing a block content entity.
    // @see block_content_theme_suggestions_test.module
    // @see \Drupal\block_content_theme_suggestions_test\Hook\BlockContentThemeSuggestionsTestHooks
    $this->drupalLogin($this->drupalCreateUser([
      'configure any layout',
      'administer node display',
    ]));
    $this->createContentType(['type' => 'bundle_with_extra_field']);
    $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default');
    $this->submitForm(['layout[enabled]' => TRUE], 'Save');
    $node = $this->createNode([
      'type' => 'bundle_with_extra_field',
      'title' => 'The first node title',
    ]);
    $node->save();
    $this->drupalGet('/node/' . $node->id());
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->pageTextContains('Example block!');
    $this->assertSession()->pageTextContains('I am a block content template for a specific bundle and view mode!');
  }

}
Loading