Version 1
[yaffs-website] / web / core / modules / content_moderation / src / Access / LatestRevisionCheck.php
1 <?php
2
3 namespace Drupal\content_moderation\Access;
4
5 use Drupal\Core\Access\AccessResult;
6 use Drupal\Core\Entity\EntityInterface;
7 use Drupal\Core\Routing\Access\AccessInterface;
8 use Drupal\Core\Routing\RouteMatchInterface;
9 use Drupal\content_moderation\ModerationInformationInterface;
10 use Drupal\Core\Session\AccountInterface;
11 use Drupal\user\EntityOwnerInterface;
12 use Symfony\Component\Routing\Route;
13
14 /**
15  * Access check for the entity moderation tab.
16  */
17 class LatestRevisionCheck implements AccessInterface {
18
19   /**
20    * The moderation information service.
21    *
22    * @var \Drupal\content_moderation\ModerationInformationInterface
23    */
24   protected $moderationInfo;
25
26   /**
27    * Constructs a new LatestRevisionCheck.
28    *
29    * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_information
30    *   The moderation information service.
31    */
32   public function __construct(ModerationInformationInterface $moderation_information) {
33     $this->moderationInfo = $moderation_information;
34   }
35
36   /**
37    * Checks that there is a forward revision available.
38    *
39    * This checker assumes the presence of an '_entity_access' requirement key
40    * in the same form as used by EntityAccessCheck.
41    *
42    * @param \Symfony\Component\Routing\Route $route
43    *   The route to check against.
44    * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
45    *   The parametrized route.
46    * @param \Drupal\Core\Session\AccountInterface $account
47    *   The current user account.
48    *
49    * @return \Drupal\Core\Access\AccessResultInterface
50    *   The access result.
51    *
52    * @see \Drupal\Core\Entity\EntityAccessCheck
53    */
54   public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) {
55     // This tab should not show up unless there's a reason to show it.
56     $entity = $this->loadEntity($route, $route_match);
57     if ($this->moderationInfo->hasForwardRevision($entity)) {
58       // Check the global permissions first.
59       $access_result = AccessResult::allowedIfHasPermissions($account, ['view latest version', 'view any unpublished content']);
60       if (!$access_result->isAllowed()) {
61         // Check entity owner access.
62         $owner_access = AccessResult::allowedIfHasPermissions($account, ['view latest version', 'view own unpublished content']);
63         $owner_access = $owner_access->andIf((AccessResult::allowedIf($entity instanceof EntityOwnerInterface && ($entity->getOwnerId() == $account->id()))));
64         $access_result = $access_result->orIf($owner_access);
65       }
66
67       return $access_result->addCacheableDependency($entity);
68     }
69
70     return AccessResult::forbidden()->addCacheableDependency($entity);
71   }
72
73   /**
74    * Returns the default revision of the entity this route is for.
75    *
76    * @param \Symfony\Component\Routing\Route $route
77    *   The route to check against.
78    * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
79    *   The parametrized route.
80    *
81    * @return \Drupal\Core\Entity\ContentEntityInterface
82    *   returns the Entity in question.
83    *
84    * @throws \Exception
85    *   A generic exception is thrown if the entity couldn't be loaded. This
86    *   almost always implies a developer error, so it should get turned into
87    *   an HTTP 500.
88    */
89   protected function loadEntity(Route $route, RouteMatchInterface $route_match) {
90     $entity_type = $route->getOption('_content_moderation_entity_type');
91
92     if ($entity = $route_match->getParameter($entity_type)) {
93       if ($entity instanceof EntityInterface) {
94         return $entity;
95       }
96     }
97     throw new \Exception(sprintf('%s is not a valid entity route. The LatestRevisionCheck access checker may only be used with a route that has a single entity parameter.', $route_match->getRouteName()));
98   }
99
100 }