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

add tests + fixes

parent f6da2d35
No related branches found
No related tags found
No related merge requests found
...@@ -11,7 +11,6 @@ use Drupal\Core\Access\AccessResult; ...@@ -11,7 +11,6 @@ use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\RevisionableInterface;
use Drupal\Core\Routing\Access\AccessInterface; use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
...@@ -48,10 +47,17 @@ class EntityRevisionRouteAccessChecker implements AccessInterface { ...@@ -48,10 +47,17 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function access(Route $route, AccountInterface $account, Request $request) { public function access(Route $route, AccountInterface $account, Request $request) {
$_entity_revision = $request->attributes->get('_entity_revision');
$operation = $route->getRequirement('_entity_access_revision'); $operation = $route->getRequirement('_entity_access_revision');
list(, $operation) = explode('.', $operation, 2); list(, $operation) = explode('.', $operation, 2);
return AccessResult::allowedIf($_entity_revision && $this->checkAccess($_entity_revision, $account, $operation))->cachePerPermissions();
if ($operation === 'list') {
$_entity = $request->attributes->get('_entity', $request->attributes->get($route->getOption('entity_type_id')));
return AccessResult::allowedIf($this->checkAccess($_entity, $account, $operation))->cachePerPermissions();
}
else {
$_entity_revision = $request->attributes->get('_entity_revision');
return AccessResult::allowedIf($_entity_revision && $this->checkAccess($_entity_revision, $account, $operation))->cachePerPermissions();
}
} }
protected function checkAccess(ContentEntityInterface $entity, AccountInterface $account, $operation = 'view') { protected function checkAccess(ContentEntityInterface $entity, AccountInterface $account, $operation = 'view') {
...@@ -64,12 +70,14 @@ class EntityRevisionRouteAccessChecker implements AccessInterface { ...@@ -64,12 +70,14 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
$map = [ $map = [
'view' => "view all $entity_type_id revisions", 'view' => "view all $entity_type_id revisions",
'list' => "view all $entity_type_id revisions",
'update' => "revert all $entity_type_id revisions", 'update' => "revert all $entity_type_id revisions",
'delete' => "delete all $entity_type_id revisions", 'delete' => "delete all $entity_type_id revisions",
]; ];
$bundle = $entity->bundle(); $bundle = $entity->bundle();
$type_map = [ $type_map = [
'view' => "view $entity_type_id $bundle revisions", 'view' => "view $entity_type_id $bundle revisions",
'list' => "view $entity_type_id $bundle revisions",
'update' => "revert $entity_type_id $bundle revisions", 'update' => "revert $entity_type_id $bundle revisions",
'delete' => "delete $entity_type_id $bundle revisions", 'delete' => "delete $entity_type_id $bundle revisions",
]; ];
......
...@@ -10,15 +10,12 @@ namespace Drupal\entity\Controller; ...@@ -10,15 +10,12 @@ namespace Drupal\entity\Controller;
use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/** /**
* Defines a trait for common revision UI functionality. * Defines a trait for common revision UI functionality.
*/ */
trait RevisionControllerTrait { trait RevisionControllerTrait {
use StringTranslationTrait;
/** /**
* @return \Drupal\Core\Entity\EntityTypeManagerInterface * @return \Drupal\Core\Entity\EntityTypeManagerInterface
*/ */
...@@ -116,7 +113,7 @@ trait RevisionControllerTrait { ...@@ -116,7 +113,7 @@ trait RevisionControllerTrait {
* @return array * @return array
* An array as expected by drupal_render(). * An array as expected by drupal_render().
*/ */
public function revisionOverview(ContentEntityInterface $entity) { protected function revisionOverview(ContentEntityInterface $entity) {
$langcode = $this->languageManager() $langcode = $this->languageManager()
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT) ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId(); ->getId();
...@@ -133,16 +130,15 @@ trait RevisionControllerTrait { ...@@ -133,16 +130,15 @@ trait RevisionControllerTrait {
return $entity_storage->loadRevision($vid); return $entity_storage->loadRevision($vid);
}, $revision_ids)); }, $revision_ids));
$latest_revision = TRUE;
foreach ($entity_revisions as $revision) { foreach ($entity_revisions as $revision) {
$row = []; $row = [];
/** @var \Drupal\Core\Entity\ContentEntityInterface $revision */ /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode) if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)
->isRevisionTranslationAffected() ->isRevisionTranslationAffected()
) { ) {
if ($latest_revision) { $row[] = $this->getRevisionDescription($revision, $revision->isDefaultRevision());
$row[] = $this->getRevisionDescription($revision, TRUE);
if ($revision->isDefaultRevision()) {
$row[] = [ $row[] = [
'data' => [ 'data' => [
'#prefix' => '<em>', '#prefix' => '<em>',
...@@ -153,18 +149,9 @@ trait RevisionControllerTrait { ...@@ -153,18 +149,9 @@ trait RevisionControllerTrait {
foreach ($row as &$current) { foreach ($row as &$current) {
$current['class'] = ['revision-current']; $current['class'] = ['revision-current'];
} }
$latest_revision = FALSE;
} }
else { else {
$row[] = $this->getRevisionDescription($revision, FALSE); $row[] = $this->getOperationLinks($revision);
$links = $this->getOperationLinks($revision);
$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
} }
} }
...@@ -203,7 +190,8 @@ trait RevisionControllerTrait { ...@@ -203,7 +190,8 @@ trait RevisionControllerTrait {
if ($delete_permission) { if ($delete_permission) {
$links['delete'] = $this->buildDeleteRevisionLink($entity_revision); $links['delete'] = $this->buildDeleteRevisionLink($entity_revision);
} }
return $links;
return array_filter($links);
} }
} }
...@@ -13,6 +13,7 @@ use Drupal\Core\Controller\ControllerBase; ...@@ -13,6 +13,7 @@ use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface; use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\entity\Revision\EntityRevisionLogInterface; use Drupal\entity\Revision\EntityRevisionLogInterface;
use Drupal\user\EntityOwnerInterface; use Drupal\user\EntityOwnerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
...@@ -56,26 +57,34 @@ class RevisionOverviewController extends ControllerBase { ...@@ -56,26 +57,34 @@ class RevisionOverviewController extends ControllerBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function buildRevertRevisionLink(EntityInterface $entity_revision) { protected function buildRevertRevisionLink(EntityInterface $entity_revision) {
return [ if ($entity_revision->hasLinkTemplate('revision-revert')) {
'title' => t('Revert'), return [
'url' => $entity_revision->toUrl('revision-revert'), 'title' => t('Revert'),
]; 'url' => $entity_revision->toUrl('revision-revert'),
];
}
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function buildDeleteRevisionLink(EntityInterface $entity_revision) { protected function buildDeleteRevisionLink(EntityInterface $entity_revision) {
return [ if ($entity_revision->hasLinkTemplate('revision-delete')) {
'title' => t('Delete'), return [
'url' => $entity_revision->toUrl('revision-delete'), 'title' => t('Delete'),
]; 'url' => $entity_revision->toUrl('revision-delete'),
];
}
}
public function revisionOverviewController(RouteMatchInterface $route_match) {
return $this->revisionOverview($route_match->getParameter($route_match->getRouteObject()->getOption('entity_type_id')));
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function getRevisionDescription(ContentEntityInterface $revision, $is_current = FALSE) { protected function getRevisionDescription(ContentEntityInterface $revision, $is_default = FALSE) {
/** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\user\EntityOwnerInterface|\Drupal\entity\Revision\EntityRevisionLogInterface $revision */ /** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\user\EntityOwnerInterface|\Drupal\entity\Revision\EntityRevisionLogInterface $revision */
if ($revision instanceof EntityOwnerInterface) { if ($revision instanceof EntityOwnerInterface) {
...@@ -91,12 +100,7 @@ class RevisionOverviewController extends ControllerBase { ...@@ -91,12 +100,7 @@ class RevisionOverviewController extends ControllerBase {
if ($revision instanceof EntityRevisionLogInterface) { if ($revision instanceof EntityRevisionLogInterface) {
// Use revision link to link to revisions that are not active. // Use revision link to link to revisions that are not active.
$date = $this->dateFormatter->format($revision->getRevisionCreationTime(), 'short'); $date = $this->dateFormatter->format($revision->getRevisionCreationTime(), 'short');
if (!$is_current) { $link = $revision->toLink($date, 'revision');
$link = $revision->toLink($date, 'revision');
}
else {
$link = $revision->toLink($date);
}
} }
else { else {
$link = $revision->toLink($revision->label(), 'revision'); $link = $revision->toLink($revision->label(), 'revision');
...@@ -119,7 +123,7 @@ class RevisionOverviewController extends ControllerBase { ...@@ -119,7 +123,7 @@ class RevisionOverviewController extends ControllerBase {
'#type' => 'inline_template', '#type' => 'inline_template',
'#template' => $template, '#template' => $template,
'#context' => [ '#context' => [
'date' => $link, 'date' => $link->toString(),
'username' => $username, 'username' => $username,
'message' => ['#markup' => $markup, '#allowed_tags' => Xss::getHtmlTagList()], 'message' => ['#markup' => $markup, '#allowed_tags' => Xss::getHtmlTagList()],
], ],
......
...@@ -113,14 +113,15 @@ class RevisionRouteProvider implements EntityRouteProviderInterface { ...@@ -113,14 +113,15 @@ class RevisionRouteProvider implements EntityRouteProviderInterface {
protected function getRevisionHistoryRoute($entity_type) { protected function getRevisionHistoryRoute($entity_type) {
if ($entity_type->hasLinkTemplate('version-history')) { if ($entity_type->hasLinkTemplate('version-history')) {
$entity_type_id = $entity_type->id(); $entity_type_id = $entity_type->id();
$route = new Route($entity_type->getLinkTemplate('revision')); $route = new Route($entity_type->getLinkTemplate('version-history'));
$route->addDefaults([ $route->addDefaults([
'_controller' => '\Drupal\entity\Controller\RevisionControllerTrait::revisionOverview', '_controller' => '\Drupal\entity\Controller\RevisionOverviewController::revisionOverviewController',
'_title' => 'Revisions', '_title' => 'Revisions',
]); ]);
$route->addRequirements([ $route->addRequirements([
'_entity_access_revision' => "$entity_type_id.view", '_entity_access_revision' => "$entity_type_id.list",
]); ]);
$route->setOption('entity_type_id', $entity_type->id());
$route->setOption('parameters', [ $route->setOption('parameters', [
$entity_type->id() => [ $entity_type->id() => [
'type' => 'entity:' . $entity_type->id(), 'type' => 'entity:' . $entity_type->id(),
......
...@@ -55,8 +55,9 @@ class RevisionBasicUITest extends KernelTestBase { ...@@ -55,8 +55,9 @@ class RevisionBasicUITest extends KernelTestBase {
$revision->isDefaultRevision(FALSE); $revision->isDefaultRevision(FALSE);
$revision->save(); $revision->save();
/** @var \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel */
$http_kernel = \Drupal::service('http_kernel'); $http_kernel = \Drupal::service('http_kernel');
$request = Request::create($revision->url('revision')); $request = Request::create($revision->url('version-history'));
$response = $http_kernel->handle($request); $response = $http_kernel->handle($request);
$this->assertEquals(403, $response->getStatusCode()); $this->assertEquals(403, $response->getStatusCode());
...@@ -71,9 +72,13 @@ class RevisionBasicUITest extends KernelTestBase { ...@@ -71,9 +72,13 @@ class RevisionBasicUITest extends KernelTestBase {
$user->addRole($role->id()); $user->addRole($role->id());
\Drupal::service('account_switcher')->switchTo($user); \Drupal::service('account_switcher')->switchTo($user);
$request = Request::create($revision->url('revision')); $request = Request::create($revision->url('version-history'));
$response = $http_kernel->handle($request); $response = $http_kernel->handle($request);
$this->assertEquals(200, $response->getStatusCode()); $this->assertEquals(200, $response->getStatusCode());
// This ensures that the default revision is still the first revision.
$this->assertTrue(strpos($response->getContent(), 'entity_test_enhanced/1/revisions/2/view') !== FALSE);
$this->assertTrue(strpos($response->getContent(), 'entity_test_enhanced/1') !== FALSE);
} }
public function testRevisionView() { public function testRevisionView() {
......
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