Unverified Commit c57b1901 authored by larowlan's avatar larowlan

Issue #2942590 by tim.plunkett: Layout Builder defaults should work regardless...

Issue #2942590 by tim.plunkett: Layout Builder defaults should work regardless of the ability to provide overrides
parent 39881968
......@@ -5,7 +5,6 @@
* Provides hook implementations for Layout Builder.
*/
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
......@@ -44,11 +43,6 @@ function layout_builder_help($route_name, RouteMatchInterface $route_match) {
*/
function layout_builder_entity_type_alter(array &$entity_types) {
/** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
foreach ($entity_types as $entity_type) {
if ($entity_type->entityClassImplements(FieldableEntityInterface::class) && $entity_type->hasLinkTemplate('canonical') && $entity_type->hasViewBuilderClass()) {
$entity_type->setLinkTemplate('layout-builder', $entity_type->getLinkTemplate('canonical') . '/layout');
}
}
$entity_types['entity_view_display']
->setClass(LayoutBuilderEntityViewDisplay::class)
->setStorageClass(LayoutBuilderEntityViewDisplayStorage::class)
......
......@@ -5,6 +5,7 @@
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -50,7 +51,7 @@ public static function create(ContainerInterface $container, $base_plugin_id) {
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
foreach ($this->getEntityTypes() as $entity_type_id => $entity_type) {
foreach ($this->getEntityTypesForOverrides() as $entity_type_id => $entity_type) {
// Overrides.
$this->derivatives["layout_builder.overrides.$entity_type_id.view"] = $base_plugin_definition + [
'route_name' => "layout_builder.overrides.$entity_type_id.view",
......@@ -81,7 +82,9 @@ public function getDerivativeDefinitions($base_plugin_definition) {
'weight' => 10,
'cache_contexts' => ['layout_builder_is_active:' . $entity_type_id],
];
}
foreach ($this->getEntityTypesForDefaults() as $entity_type_id => $entity_type) {
// Defaults.
$this->derivatives["layout_builder.defaults.$entity_type_id.view"] = $base_plugin_definition + [
'route_name' => "layout_builder.defaults.$entity_type_id.view",
......@@ -105,14 +108,26 @@ public function getDerivativeDefinitions($base_plugin_definition) {
}
/**
* Returns an array of relevant entity types.
* Returns an array of entity types relevant for defaults.
*
* @return \Drupal\Core\Entity\EntityTypeInterface[]
* An array of entity types.
*/
protected function getEntityTypesForDefaults() {
return array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $entity_type) {
return $entity_type->entityClassImplements(FieldableEntityInterface::class) && $entity_type->hasViewBuilderClass() && $entity_type->get('field_ui_base_route');
});
}
/**
* Returns an array of entity types relevant for overrides.
*
* @return \Drupal\Core\Entity\EntityTypeInterface[]
* An array of entity types.
*/
protected function getEntityTypes() {
protected function getEntityTypesForOverrides() {
return array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $entity_type) {
return $entity_type->hasLinkTemplate('layout-builder');
return $entity_type->entityClassImplements(FieldableEntityInterface::class) && $entity_type->hasViewBuilderClass() && $entity_type->hasLinkTemplate('canonical');
});
}
......
......@@ -6,6 +6,7 @@
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
......@@ -203,7 +204,7 @@ public function buildRoutes(RouteCollection $collection) {
*/
protected function getEntityTypes() {
return array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $entity_type) {
return $entity_type->hasLinkTemplate('layout-builder') && $entity_type->get('field_ui_base_route');
return $entity_type->entityClassImplements(FieldableEntityInterface::class) && $entity_type->hasViewBuilderClass() && $entity_type->get('field_ui_base_route');
});
}
......
......@@ -152,7 +152,7 @@ public function buildRoutes(RouteCollection $collection) {
$options['parameters']['section_storage'] = [];
$options['parameters'][$entity_type_id]['type'] = 'entity:' . $entity_type_id;
$template = $entity_type->getLinkTemplate('layout-builder');
$template = $entity_type->getLinkTemplate('canonical') . '/layout';
$this->buildLayoutRoutes($collection, $this->getPluginDefinition(), $template, $defaults, $requirements, $options, $entity_type_id);
}
}
......@@ -179,7 +179,7 @@ protected function hasIntegerId(EntityTypeInterface $entity_type) {
*/
protected function getEntityTypes() {
return array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $entity_type) {
return $entity_type->hasLinkTemplate('layout-builder');
return $entity_type->entityClassImplements(FieldableEntityInterface::class) && $entity_type->hasViewBuilderClass() && $entity_type->hasLinkTemplate('canonical');
});
}
......
......@@ -5,7 +5,9 @@
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityType;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator;
use Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage;
use Drupal\layout_builder\SectionStorage\SectionStorageDefinition;
......@@ -173,26 +175,41 @@ public function testGetSectionListFromIdCreate() {
*/
public function testBuildRoutes() {
$entity_types = [];
$entity_types['no_link_template'] = new EntityType(['id' => 'no_link_template']);
$entity_types['unknown_field_ui_route'] = new EntityType([
'id' => 'unknown_field_ui_route',
'links' => ['layout-builder' => '/entity/{entity}/layout'],
'entity_keys' => ['id' => 'id'],
'field_ui_base_route' => 'unknown',
]);
$entity_types['with_bundle_key'] = new EntityType([
'id' => 'with_bundle_key',
'links' => ['layout-builder' => '/entity/{entity}/layout'],
'entity_keys' => ['id' => 'id', 'bundle' => 'bundle'],
'bundle_entity_type' => 'my_bundle_type',
'field_ui_base_route' => 'known',
]);
$entity_types['with_bundle_parameter'] = new EntityType([
'id' => 'with_bundle_parameter',
'links' => ['layout-builder' => '/entity/{entity}/layout'],
'entity_keys' => ['id' => 'id'],
'field_ui_base_route' => 'with_bundle',
]);
$not_fieldable = $this->prophesize(EntityTypeInterface::class);
$not_fieldable->entityClassImplements(FieldableEntityInterface::class)->willReturn(FALSE);
$entity_types['not_fieldable'] = $not_fieldable->reveal();
$no_view_builder = $this->prophesize(EntityTypeInterface::class);
$no_view_builder->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$no_view_builder->hasViewBuilderClass()->willReturn(FALSE);
$entity_types['no_view_builder'] = $no_view_builder->reveal();
$no_field_ui_route = $this->prophesize(EntityTypeInterface::class);
$no_field_ui_route->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$no_field_ui_route->hasViewBuilderClass()->willReturn(TRUE);
$no_field_ui_route->get('field_ui_base_route')->willReturn(NULL);
$entity_types['no_field_ui_route'] = $no_field_ui_route->reveal();
$unknown_field_ui_route = $this->prophesize(EntityTypeInterface::class);
$unknown_field_ui_route->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$unknown_field_ui_route->hasViewBuilderClass()->willReturn(TRUE);
$unknown_field_ui_route->get('field_ui_base_route')->willReturn('unknown');
$entity_types['unknown_field_ui_route'] = $unknown_field_ui_route->reveal();
$with_bundle_key = $this->prophesize(EntityTypeInterface::class);
$with_bundle_key->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$with_bundle_key->hasViewBuilderClass()->willReturn(TRUE);
$with_bundle_key->get('field_ui_base_route')->willReturn('known');
$with_bundle_key->hasKey('bundle')->willReturn(TRUE);
$with_bundle_key->getBundleEntityType()->willReturn('my_bundle_type');
$entity_types['with_bundle_key'] = $with_bundle_key->reveal();
$with_bundle_parameter = $this->prophesize(EntityTypeInterface::class);
$with_bundle_parameter->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$with_bundle_parameter->hasViewBuilderClass()->willReturn(TRUE);
$with_bundle_parameter->get('field_ui_base_route')->willReturn('with_bundle');
$entity_types['with_bundle_parameter'] = $with_bundle_parameter->reveal();
$this->entityTypeManager->getDefinitions()->willReturn($entity_types);
$expected = [
......
......@@ -4,7 +4,7 @@
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityType;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
......@@ -168,23 +168,42 @@ public function providerTestGetSectionListFromId() {
public function testBuildRoutes() {
$entity_types = [];
$entity_types['no_link_template'] = new EntityType(['id' => 'no_link_template']);
$this->entityFieldManager->getFieldStorageDefinitions('no_link_template')->shouldNotBeCalled();
$not_fieldable = $this->prophesize(EntityTypeInterface::class);
$not_fieldable->entityClassImplements(FieldableEntityInterface::class)->willReturn(FALSE);
$entity_types['not_fieldable'] = $not_fieldable->reveal();
$entity_types['with_string_id'] = new EntityType([
'id' => 'with_string_id',
'links' => ['layout-builder' => '/entity/{entity}/layout'],
'entity_keys' => ['id' => 'id'],
]);
$no_view_builder = $this->prophesize(EntityTypeInterface::class);
$no_view_builder->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$no_view_builder->hasViewBuilderClass()->willReturn(FALSE);
$entity_types['no_view_builder'] = $no_view_builder->reveal();
$no_canonical_link = $this->prophesize(EntityTypeInterface::class);
$no_canonical_link->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$no_canonical_link->hasViewBuilderClass()->willReturn(TRUE);
$no_canonical_link->hasLinkTemplate('canonical')->willReturn(FALSE);
$entity_types['no_canonical_link'] = $no_canonical_link->reveal();
$this->entityFieldManager->getFieldStorageDefinitions('no_canonical_link')->shouldNotBeCalled();
$with_string_id = $this->prophesize(EntityTypeInterface::class);
$with_string_id->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$with_string_id->hasViewBuilderClass()->willReturn(TRUE);
$with_string_id->hasLinkTemplate('canonical')->willReturn(TRUE);
$with_string_id->getLinkTemplate('canonical')->willReturn('/entity/{entity}');
$with_string_id->id()->willReturn('with_string_id');
$with_string_id->getKey('id')->willReturn('id');
$entity_types['with_string_id'] = $with_string_id->reveal();
$string_id = $this->prophesize(FieldStorageDefinitionInterface::class);
$string_id->getType()->willReturn('string');
$this->entityFieldManager->getFieldStorageDefinitions('with_string_id')->willReturn(['id' => $string_id->reveal()]);
$entity_types['with_integer_id'] = new EntityType([
'id' => 'with_integer_id',
'links' => ['layout-builder' => '/entity/{entity}/layout'],
'entity_keys' => ['id' => 'id'],
]);
$with_integer_id = $this->prophesize(EntityTypeInterface::class);
$with_integer_id->entityClassImplements(FieldableEntityInterface::class)->willReturn(TRUE);
$with_integer_id->hasViewBuilderClass()->willReturn(TRUE);
$with_integer_id->hasLinkTemplate('canonical')->willReturn(TRUE);
$with_integer_id->getLinkTemplate('canonical')->willReturn('/entity/{entity}');
$with_integer_id->id()->willReturn('with_integer_id');
$with_integer_id->getKey('id')->willReturn('id');
$entity_types['with_integer_id'] = $with_integer_id->reveal();
$integer_id = $this->prophesize(FieldStorageDefinitionInterface::class);
$integer_id->getType()->willReturn('integer');
$this->entityFieldManager->getFieldStorageDefinitions('with_integer_id')->willReturn(['id' => $integer_id->reveal()]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment