Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\comment;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Core\Access\AccessResult;
|
Chris@0
|
6 use Drupal\Core\Entity\EntityAccessControlHandler;
|
Chris@0
|
7 use Drupal\Core\Entity\EntityInterface;
|
Chris@0
|
8 use Drupal\Core\Field\FieldDefinitionInterface;
|
Chris@0
|
9 use Drupal\Core\Field\FieldItemListInterface;
|
Chris@0
|
10 use Drupal\Core\Session\AccountInterface;
|
Chris@0
|
11
|
Chris@0
|
12 /**
|
Chris@0
|
13 * Defines the access control handler for the comment entity type.
|
Chris@0
|
14 *
|
Chris@0
|
15 * @see \Drupal\comment\Entity\Comment
|
Chris@0
|
16 */
|
Chris@0
|
17 class CommentAccessControlHandler extends EntityAccessControlHandler {
|
Chris@0
|
18
|
Chris@0
|
19 /**
|
Chris@0
|
20 * {@inheritdoc}
|
Chris@0
|
21 */
|
Chris@0
|
22 protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
Chris@0
|
23 /** @var \Drupal\comment\CommentInterface|\Drupal\user\EntityOwnerInterface $entity */
|
Chris@0
|
24
|
Chris@0
|
25 $comment_admin = $account->hasPermission('administer comments');
|
Chris@0
|
26 if ($operation == 'approve') {
|
Chris@0
|
27 return AccessResult::allowedIf($comment_admin && !$entity->isPublished())
|
Chris@0
|
28 ->cachePerPermissions()
|
Chris@0
|
29 ->addCacheableDependency($entity);
|
Chris@0
|
30 }
|
Chris@0
|
31
|
Chris@0
|
32 if ($comment_admin) {
|
Chris@0
|
33 $access = AccessResult::allowed()->cachePerPermissions();
|
Chris@0
|
34 return ($operation != 'view') ? $access : $access->andIf($entity->getCommentedEntity()->access($operation, $account, TRUE));
|
Chris@0
|
35 }
|
Chris@0
|
36
|
Chris@0
|
37 switch ($operation) {
|
Chris@0
|
38 case 'view':
|
Chris@0
|
39 $access_result = AccessResult::allowedIf($account->hasPermission('access comments') && $entity->isPublished())->cachePerPermissions()->addCacheableDependency($entity)
|
Chris@0
|
40 ->andIf($entity->getCommentedEntity()->access($operation, $account, TRUE));
|
Chris@0
|
41 if (!$access_result->isAllowed()) {
|
Chris@0
|
42 $access_result->setReason("The 'access comments' permission is required and the comment must be published.");
|
Chris@0
|
43 }
|
Chris@0
|
44
|
Chris@0
|
45 return $access_result;
|
Chris@0
|
46
|
Chris@0
|
47 case 'update':
|
Chris@17
|
48 $access_result = AccessResult::allowedIf($account->id() && $account->id() == $entity->getOwnerId() && $entity->isPublished() && $account->hasPermission('edit own comments'))
|
Chris@17
|
49 ->cachePerPermissions()->cachePerUser()->addCacheableDependency($entity);
|
Chris@17
|
50 if (!$access_result->isAllowed()) {
|
Chris@17
|
51 $access_result->setReason("The 'edit own comments' permission is required, the user must be the comment author, and the comment must be published.");
|
Chris@17
|
52 }
|
Chris@17
|
53 return $access_result;
|
Chris@0
|
54
|
Chris@0
|
55 default:
|
Chris@0
|
56 // No opinion.
|
Chris@0
|
57 return AccessResult::neutral()->cachePerPermissions();
|
Chris@0
|
58 }
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@0
|
61 /**
|
Chris@0
|
62 * {@inheritdoc}
|
Chris@0
|
63 */
|
Chris@0
|
64 protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
|
Chris@0
|
65 return AccessResult::allowedIfHasPermission($account, 'post comments');
|
Chris@0
|
66 }
|
Chris@0
|
67
|
Chris@0
|
68 /**
|
Chris@0
|
69 * {@inheritdoc}
|
Chris@0
|
70 */
|
Chris@0
|
71 protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
|
Chris@0
|
72 if ($operation == 'edit') {
|
Chris@0
|
73 // Only users with the "administer comments" permission can edit
|
Chris@0
|
74 // administrative fields.
|
Chris@0
|
75 $administrative_fields = [
|
Chris@0
|
76 'uid',
|
Chris@0
|
77 'status',
|
Chris@0
|
78 'created',
|
Chris@0
|
79 'date',
|
Chris@0
|
80 ];
|
Chris@0
|
81 if (in_array($field_definition->getName(), $administrative_fields, TRUE)) {
|
Chris@0
|
82 return AccessResult::allowedIfHasPermission($account, 'administer comments');
|
Chris@0
|
83 }
|
Chris@0
|
84
|
Chris@0
|
85 // No user can change read-only fields.
|
Chris@0
|
86 $read_only_fields = [
|
Chris@0
|
87 'hostname',
|
Chris@0
|
88 'changed',
|
Chris@0
|
89 'cid',
|
Chris@0
|
90 'thread',
|
Chris@0
|
91 ];
|
Chris@0
|
92 // These fields can be edited during comment creation.
|
Chris@0
|
93 $create_only_fields = [
|
Chris@0
|
94 'comment_type',
|
Chris@0
|
95 'uuid',
|
Chris@0
|
96 'entity_id',
|
Chris@0
|
97 'entity_type',
|
Chris@0
|
98 'field_name',
|
Chris@0
|
99 'pid',
|
Chris@0
|
100 ];
|
Chris@0
|
101 if ($items && ($entity = $items->getEntity()) && $entity->isNew() && in_array($field_definition->getName(), $create_only_fields, TRUE)) {
|
Chris@0
|
102 // We are creating a new comment, user can edit create only fields.
|
Chris@0
|
103 return AccessResult::allowedIfHasPermission($account, 'post comments')->addCacheableDependency($entity);
|
Chris@0
|
104 }
|
Chris@0
|
105 // We are editing an existing comment - create only fields are now read
|
Chris@0
|
106 // only.
|
Chris@0
|
107 $read_only_fields = array_merge($read_only_fields, $create_only_fields);
|
Chris@0
|
108 if (in_array($field_definition->getName(), $read_only_fields, TRUE)) {
|
Chris@0
|
109 return AccessResult::forbidden();
|
Chris@0
|
110 }
|
Chris@0
|
111
|
Chris@0
|
112 // If the field is configured to accept anonymous contact details - admins
|
Chris@0
|
113 // can edit name, homepage and mail. Anonymous users can also fill in the
|
Chris@0
|
114 // fields on comment creation.
|
Chris@0
|
115 if (in_array($field_definition->getName(), ['name', 'mail', 'homepage'], TRUE)) {
|
Chris@0
|
116 if (!$items) {
|
Chris@0
|
117 // We cannot make a decision about access to edit these fields if we
|
Chris@0
|
118 // don't have any items and therefore cannot determine the Comment
|
Chris@0
|
119 // entity. In this case we err on the side of caution and prevent edit
|
Chris@0
|
120 // access.
|
Chris@0
|
121 return AccessResult::forbidden();
|
Chris@0
|
122 }
|
Chris@0
|
123 $is_name = $field_definition->getName() === 'name';
|
Chris@0
|
124 /** @var \Drupal\comment\CommentInterface $entity */
|
Chris@0
|
125 $entity = $items->getEntity();
|
Chris@0
|
126 $commented_entity = $entity->getCommentedEntity();
|
Chris@0
|
127 $anonymous_contact = $commented_entity->get($entity->getFieldName())->getFieldDefinition()->getSetting('anonymous');
|
Chris@0
|
128 $admin_access = AccessResult::allowedIfHasPermission($account, 'administer comments');
|
Chris@18
|
129 $anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && ($anonymous_contact != CommentInterface::ANONYMOUS_MAYNOT_CONTACT || $is_name) && $account->hasPermission('post comments'))
|
Chris@0
|
130 ->cachePerPermissions()
|
Chris@0
|
131 ->addCacheableDependency($entity)
|
Chris@0
|
132 ->addCacheableDependency($field_definition->getConfig($commented_entity->bundle()))
|
Chris@0
|
133 ->addCacheableDependency($commented_entity);
|
Chris@0
|
134 return $admin_access->orIf($anonymous_access);
|
Chris@0
|
135 }
|
Chris@0
|
136 }
|
Chris@0
|
137
|
Chris@0
|
138 if ($operation == 'view') {
|
Chris@0
|
139 // Nobody has access to the hostname.
|
Chris@0
|
140 if ($field_definition->getName() == 'hostname') {
|
Chris@0
|
141 return AccessResult::forbidden();
|
Chris@0
|
142 }
|
Chris@0
|
143 // The mail field is hidden from non-admins.
|
Chris@0
|
144 if ($field_definition->getName() == 'mail') {
|
Chris@0
|
145 return AccessResult::allowedIfHasPermission($account, 'administer comments');
|
Chris@0
|
146 }
|
Chris@0
|
147 }
|
Chris@0
|
148 return parent::checkFieldAccess($operation, $field_definition, $account, $items);
|
Chris@0
|
149 }
|
Chris@0
|
150
|
Chris@0
|
151 }
|