Skip to content
Snippets Groups Projects
Commit 99f8e3e6 authored by Daniel Wehner's avatar Daniel Wehner
Browse files

Add a revision view controller

parent a9b5308a
No related branches found
No related tags found
No related merge requests found
......@@ -9,3 +9,10 @@ services:
class: Drupal\entity\RouteEnhancer\EntityRevisionRouteEnhancer
tags:
- { name: route_enhancer, priority: 20 }
access_checker.entity_revision:
class: \Drupal\entity\Access\EntityRevisionRouteAccessChecker
arguments: ['@entity_type.manager']
tags:
- { name: access_check, applies_to: _entity_access_revision, needs_request: TRUE }
......@@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\RevisionableInterface;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
/**
......@@ -46,7 +47,8 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
/**
* {@inheritdoc}
*/
public function access(Route $route, AccountInterface $account, RevisionableInterface $_entity_revision) {
public function access(Route $route, AccountInterface $account, Request $request) {
$_entity_revision = $request->attributes->get('_entity_revision');
$operation = $route->getRequirement('_entity_access_revision');
list(, $operation) = explode('.', $operation, 2);
return AccessResult::allowedIf($_entity_revision && $this->checkAccess($_entity_revision, $account, $operation))->cachePerPermissions();
......
<?php
/**
* @file
* Contains \Drupal\entity\Controller\RevisionController.
*/
namespace Drupal\entity\Controller;
use Drupal\Core\Entity\Controller\EntityViewController;
use Drupal\Core\Entity\EntityInterface;
/**
* Provides some controllers related with entity revisions.
*/
class RevisionController extends EntityViewController {
/**
* Provides a page to render a single entity revision.
*
* @param \Drupal\Core\Entity\EntityInterface $_entity_revision
* The Entity to be rendered. Note this variable is named $_entity_revision
* rather than $entity to prevent collisions with other named placeholders
* in the route.
* @param string $view_mode
* (optional) The view mode that should be used to display the entity.
* Defaults to 'full'.
*
* @return array
* A render array.
*/
public function view(EntityInterface $_entity_revision, $view_mode = 'full') {
return parent::view($_entity_revision, $view_mode);
}
}
<?php
/**
* @file
* Contains \Drupal\entity\Routing\RevisionRouteProvider.
*/
namespace Drupal\entity\Routing;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\Routing\EntityRouteProviderInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* Provides revision routes.
*/
class RevisionRouteProvider implements EntityRouteProviderInterface {
/**
* {@inheritdoc}
*/
public function getRoutes(EntityTypeInterface $entity_type) {
$collection = new RouteCollection();
$entity_type_id = $entity_type->id();
if ($view_route = $this->getRevisionViewRoute($entity_type)) {
$collection->add("entity.$entity_type_id.revision", $view_route);
}
return $collection;
}
/**
* Gets the entity revision view route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionViewRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('revision')) {
$entity_type_id = $entity_type->id();
$route = new Route($entity_type->getLinkTemplate('revision'));
$route->addDefaults([
'_controller' => '\Drupal\entity\Controller\RevisionController::view',
'_title_callback' => '\Drupal\Core\Entity\Controller\EntityController::title',
]);
$route->addRequirements([
'_entity_access_revision' => "$entity_type_id.view",
]);
$route->setOption('parameters', [
$entity_type->id() => [
'type' => 'entity:' . $entity_type->id(),
],
$entity_type->id() . '_revision' => [
'type' => 'entity_revision:' . $entity_type->id(),
],
]);
return $route;
}
}
}
<?php
/**
* @file
* Contains \Drupal\Tests\entity\Kernel\RevisionBasicUITest.
*/
namespace Drupal\Tests\entity\Kernel;
use Drupal\entity_module_test\Entity\EntityWithRevisionRoutes;
use Drupal\KernelTests\KernelTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\Entity\User;
use Symfony\Component\HttpFoundation\Request;
/**
* @group entity
*/
class RevisionBasicUITest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['entity_module_test', 'system', 'user', 'entity'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('user');
$this->installEntitySchema('entity_test__rev_routes');
$this->installSchema('system', 'router');
\Drupal::service('router.builder')->rebuild();
}
public function testRevisionView() {
$entity = EntityWithRevisionRoutes::create([]);
$entity->save();
$revision = clone $entity;
$revision->setNewRevision(TRUE);
$revision->isDefaultRevision(FALSE);
$revision->save();
/** @var \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel */
$http_kernel = \Drupal::service('http_kernel');
$request = Request::create($revision->url('revision'));
$response = $http_kernel->handle($request);
$this->assertEquals(403, $response->getStatusCode());
$role = Role::create(['id' => 'test_role']);
$role->grantPermission('view all entity_test__rev_routes revisions');
$role->grantPermission('administer entity_test__revision_routes');
$role->save();
$user = User::create([
'name' => 'Test user',
]);
$user->addRole($role->id());
\Drupal::service('account_switcher')->switchTo($user);
$request = Request::create($revision->url('revision'));
$response = $http_kernel->handle($request);
$this->assertEquals(200, $response->getStatusCode());
}
}
<?php
/**
* @file
* Contains \Drupal\entity_module_test\Entity\EntityWithRevisionRoutes.
*/
namespace Drupal\entity_module_test\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\entity\EntityKeysFieldsTrait;
use Drupal\entity\Revision\EntityRevisionLogTrait;
/**
* @ContentEntityType(
* id = "entity_test__rev_routes",
* label = @Translation("Entity test with revision routes"),
* handlers = {
* "storage" = "\Drupal\Core\Entity\Sql\SqlContentEntityStorage",
* "route_provider" = {
* "revision" = "\Drupal\entity\Routing\RevisionRouteProvider",
* },
* },
* base_table = "entity_test__revision_routes",
* data_table = "entity_test__revision_routes__field_data",
* revision_table = "entity_test__revision_routes__revision",
* revision_data_table = "entity_test__revision_routes__field_revision",
* translatable = TRUE,
* revisionable = TRUE,
* admin_permission = "administer entity_test__revision_routes",
* entity_keys = {
* "id" = "id",
* "revision" = "vid",
* "langcode" = "langcode",
* },
* links = {
* "revision" = "/entity_test__rev_routes/{entity_test__rev_routes}/revisions/{entity_test__rev_routes_revision}/view",
* }
* )
*/
class EntityWithRevisionRoutes extends ContentEntityBase {
use EntityRevisionLogTrait;
use EntityKeysFieldsTrait;
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = [];
$fields += static::entityKeysBaseFieldDefinitions($entity_type);
return $fields;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment