Commit edb618f5 authored by catch's avatar catch

Issue #2651716 by tstoeckler, bojanz: Entity::getEntityFromRouteMatch() should support bundles

parent 9de35948
......@@ -358,7 +358,19 @@ public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entit
$entity = $route_match->getParameter($entity_type_id);
}
else {
$entity = $this->entityManager->getStorage($entity_type_id)->create([]);
$values = [];
// If the entity has bundles, fetch it from the route match.
$entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
if ($bundle_key = $entity_type->getKey('bundle')) {
if (($bundle_entity_type_id = $entity_type->getBundleEntityType()) && $route_match->getRawParameter($bundle_entity_type_id)) {
$values[$bundle_key] = $route_match->getParameter($bundle_entity_type_id)->id();
}
elseif ($route_match->getRawParameter($bundle_key)) {
$values[$bundle_key] = $route_match->getParameter($bundle_key);
}
}
$entity = $this->entityTypeManager->getStorage($entity_type_id)->create($values);
}
return $entity;
......
......@@ -67,6 +67,8 @@ function entity_test_entity_types($filter = NULL) {
}
if ($filter === ENTITY_TEST_TYPES_ROUTING) {
$types[] = 'entity_test_base_field_display';
$types[] = 'entity_test_string_id';
$types[] = 'entity_test_no_id';
}
$types[] = 'entity_test_mulrev';
$types[] = 'entity_test_mulrev_changed';
......
......@@ -44,24 +44,6 @@ public static function create(ContainerInterface $container) {
);
}
/**
* Displays the 'Add new entity_test' form.
*
* @param string $entity_type_id
* Name of the entity type for which a create form should be displayed.
*
* @return array
* The processed form for a new entity_test.
*
* @see \Drupal\entity_test\Routing\EntityTestRoutes::routes()
*/
public function testAdd($entity_type_id) {
$entity = entity_create($entity_type_id, array());
$form = $this->entityFormBuilder()->getForm($entity);
$form['#title'] = $this->t('Create an @type', array('@type' => $entity_type_id));
return $form;
}
/**
* Returns an empty page.
*
......
......@@ -47,6 +47,7 @@
* },
* links = {
* "canonical" = "/entity_test/{entity_test}",
* "add-form" = "/entity_test/add",
* "edit-form" = "/entity_test/manage/{entity_test}/edit",
* "delete-form" = "/entity_test/delete/entity_test/{entity_test}",
* },
......
......@@ -38,6 +38,7 @@
* },
* links = {
* "canonical" = "/entity_test_base_field_display/{entity_test_base_field_display}/edit",
* "add-form" = "/entity_test_base_field_display/add",
* "edit-form" = "/entity_test_base_field_display/manage/{entity_test_base_field_display}",
* "delete-form" = "/entity_test/delete/entity_test_base_field_display/{entity_test_base_field_display}/edit",
* },
......
......@@ -19,7 +19,11 @@
* entity_keys = {
* "bundle" = "type",
* },
* admin_permission = "administer entity_test content",
* field_ui_base_route = "entity.entity_test_no_id.admin_form",
* links = {
* "add-form" = "/entity_test_no_id/add",
* },
* )
*/
class EntityTestNoId extends EntityTest {
......
......@@ -34,6 +34,7 @@
* },
* links = {
* "canonical" = "/entity_test_string_id/manage/{entity_test_string_id}",
* "add-form" = "/entity_test_string_id/add",
* "edit-form" = "/entity_test_string_id/manage/{entity_test_string_id}",
* },
* field_ui_base_route = "entity.entity_test_string_id.admin_form",
......
......@@ -22,14 +22,12 @@ class EntityTestRoutes {
*/
public function routes() {
$types = entity_test_entity_types(ENTITY_TEST_TYPES_ROUTING);
$types[] = 'entity_test_string_id';
$types[] = 'entity_test_no_id';
$routes = array();
foreach ($types as $entity_type_id) {
$routes["entity.$entity_type_id.add_form"] = new Route(
"$entity_type_id/add",
array('_controller' => '\Drupal\entity_test\Controller\EntityTestController::testAdd', 'entity_type_id' => $entity_type_id),
array('_entity_form' => "$entity_type_id.default"),
array('_permission' => 'administer entity_test content')
);
......
......@@ -8,8 +8,14 @@
namespace Drupal\Tests\Core\Entity;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityType;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Routing\RouteMatch;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\Routing\Route;
/**
* @coversDefaultClass \Drupal\Core\Entity\EntityForm
......@@ -24,6 +30,13 @@ class EntityFormTest extends UnitTestCase {
*/
protected $entityForm;
/**
* A fake entity type used in the test.
*
* @var \Drupal\Core\Entity\EntityTypeInterface
*/
protected $entityType;
/**
* {@inheritdoc}
*/
......@@ -31,6 +44,7 @@ protected function setUp() {
parent::setUp();
$this->entityForm = new EntityForm();
$this->entityType = new EntityType(['id' => 'entity_test']);
}
/**
......@@ -41,17 +55,13 @@ protected function setUp() {
* @dataProvider providerTestFormIds
*/
public function testFormId($expected, $definition) {
$entity_type = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
$entity_type->expects($this->any())
->method('hasKey')
->with('bundle')
->will($this->returnValue($definition['bundle']));
$this->entityType->set('entity_keys', ['bundle' => $definition['bundle']]);
$entity = $this->getMockForAbstractClass('Drupal\Core\Entity\Entity', array(array(), $definition['entity_type']), '', TRUE, TRUE, TRUE, array('getEntityType', 'bundle'));
$entity->expects($this->any())
->method('getEntityType')
->will($this->returnValue($entity_type));
->will($this->returnValue($this->entityType));
$entity->expects($this->any())
->method('bundle')
->will($this->returnValue($definition['bundle']));
......@@ -123,4 +133,115 @@ public function testCopyFormValuesToEntity() {
$this->assertNull($result->get('key_controlled_by_plugin_collection'));
}
/**
* Tests EntityForm::getEntityFromRouteMatch() for edit and delete forms.
*
* @covers ::getEntityFromRouteMatch
*/
public function testGetEntityFromRouteMatchEditDelete() {
$entity = $this->prophesize(EntityInterface::class)->reveal();
$id = $this->entityType->id();
$route_match = new RouteMatch(
'test_route',
new Route('/entity-test/manage/{' . $id . '}/edit'),
[$id => $entity],
[$id => 1]
);
$actual = $this->entityForm->getEntityFromRouteMatch($route_match, $id);
$this->assertEquals($entity, $actual);
}
/**
* Tests EntityForm::getEntityFromRouteMatch() for add forms without a bundle.
*
* @covers ::getEntityFromRouteMatch
*/
public function testGetEntityFromRouteMatchAdd() {
$entity = $this->prophesize(EntityInterface::class)->reveal();
$this->setUpStorage()->create([])->willReturn($entity);
$route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
$actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
$this->assertEquals($entity, $actual);
}
/**
* Tests EntityForm::getEntityFromRouteMatch() with a static bundle.
*
* @covers ::getEntityFromRouteMatch
*/
public function testGetEntityFromRouteMatchAddStatic() {
$entity = $this->prophesize(EntityInterface::class)->reveal();
$bundle_key = 'bundle';
$bundle = 'test_bundle';
$this->entityType->set('entity_keys', ['bundle' => $bundle_key]);
$storage = $this->setUpStorage();
// Test without a bundle parameter in the route.
$storage->create([])->willReturn($entity);
$route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
$actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
$this->assertEquals($entity, $actual);
// Test with a static bundle parameter.
$storage->create([$bundle_key => 'test_bundle'])->willReturn($entity);
$route_match = new RouteMatch(
'test_route',
new Route('/entity-test/add/{' . $bundle_key . '}'),
[$bundle_key => $bundle],
[$bundle_key => $bundle]
);
$actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
$this->assertEquals($entity, $actual);
}
/**
* Tests EntityForm::getEntityFromRouteMatch() with a config entity bundle.
*
* @covers ::getEntityFromRouteMatch
*/
public function testGetEntityFromRouteMatchAddEntity() {
$entity = $this->prophesize(EntityInterface::class)->reveal();
$bundle_entity_type_id = 'entity_test_bundle';
$bundle = 'test_entity_bundle';
$this->entityType->set('bundle_entity_type', $bundle_entity_type_id);
$storage = $this->setUpStorage();
// Test without a bundle parameter in the route.
$storage->create([])->willReturn($entity);
$route_match = new RouteMatch('test_route', new Route('/entity-test/add'));
$actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
$this->assertEquals($entity, $actual);
// Test with an entity bundle parameter.
$storage->create(['bundle' => $bundle])->willReturn($entity);
$bundle_entity = $this->prophesize(EntityInterface::class);
$bundle_entity->id()->willReturn('test_entity_bundle');
$route_match = new RouteMatch(
'test_route',
new Route('/entity-test/add/{entity_test_bundle}'),
[$bundle_entity_type_id => $bundle_entity->reveal()],
[$bundle_entity_type_id => $bundle]
);
$actual = $this->entityForm->getEntityFromRouteMatch($route_match, $this->entityType->id());
$this->assertEquals($entity, $actual);
}
/**
* Sets up the storage accessed via the entity type manager in the form.
*
* @return \Prophecy\Prophecy\ObjectProphecy
* The storage prophecy.
*/
protected function setUpStorage() {
$storage = $this->prophesize(EntityStorageInterface::class);
$entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
$entity_type_manager->getDefinition($this->entityType->id())->willReturn($this->entityType);
$entity_type_manager->getStorage($this->entityType->id())->willReturn($storage->reveal());
$this->entityForm->setEntityTypeManager($entity_type_manager->reveal());
return $storage;
}
}
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