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@0
|
48 return AccessResult::allowedIf($account->id() && $account->id() == $entity->getOwnerId() && $entity->isPublished() && $account->hasPermission('edit own comments'))->cachePerPermissions()->cachePerUser()->addCacheableDependency($entity);
|
Chris@0
|
49
|
Chris@0
|
50 default:
|
Chris@0
|
51 // No opinion.
|
Chris@0
|
52 return AccessResult::neutral()->cachePerPermissions();
|
Chris@0
|
53 }
|
Chris@0
|
54 }
|
Chris@0
|
55
|
Chris@0
|
56 /**
|
Chris@0
|
57 * {@inheritdoc}
|
Chris@0
|
58 */
|
Chris@0
|
59 protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
|
Chris@0
|
60 return AccessResult::allowedIfHasPermission($account, 'post comments');
|
Chris@0
|
61 }
|
Chris@0
|
62
|
Chris@0
|
63 /**
|
Chris@0
|
64 * {@inheritdoc}
|
Chris@0
|
65 */
|
Chris@0
|
66 protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
|
Chris@0
|
67 if ($operation == 'edit') {
|
Chris@0
|
68 // Only users with the "administer comments" permission can edit
|
Chris@0
|
69 // administrative fields.
|
Chris@0
|
70 $administrative_fields = [
|
Chris@0
|
71 'uid',
|
Chris@0
|
72 'status',
|
Chris@0
|
73 'created',
|
Chris@0
|
74 'date',
|
Chris@0
|
75 ];
|
Chris@0
|
76 if (in_array($field_definition->getName(), $administrative_fields, TRUE)) {
|
Chris@0
|
77 return AccessResult::allowedIfHasPermission($account, 'administer comments');
|
Chris@0
|
78 }
|
Chris@0
|
79
|
Chris@0
|
80 // No user can change read-only fields.
|
Chris@0
|
81 $read_only_fields = [
|
Chris@0
|
82 'hostname',
|
Chris@0
|
83 'changed',
|
Chris@0
|
84 'cid',
|
Chris@0
|
85 'thread',
|
Chris@0
|
86 ];
|
Chris@0
|
87 // These fields can be edited during comment creation.
|
Chris@0
|
88 $create_only_fields = [
|
Chris@0
|
89 'comment_type',
|
Chris@0
|
90 'uuid',
|
Chris@0
|
91 'entity_id',
|
Chris@0
|
92 'entity_type',
|
Chris@0
|
93 'field_name',
|
Chris@0
|
94 'pid',
|
Chris@0
|
95 ];
|
Chris@0
|
96 if ($items && ($entity = $items->getEntity()) && $entity->isNew() && in_array($field_definition->getName(), $create_only_fields, TRUE)) {
|
Chris@0
|
97 // We are creating a new comment, user can edit create only fields.
|
Chris@0
|
98 return AccessResult::allowedIfHasPermission($account, 'post comments')->addCacheableDependency($entity);
|
Chris@0
|
99 }
|
Chris@0
|
100 // We are editing an existing comment - create only fields are now read
|
Chris@0
|
101 // only.
|
Chris@0
|
102 $read_only_fields = array_merge($read_only_fields, $create_only_fields);
|
Chris@0
|
103 if (in_array($field_definition->getName(), $read_only_fields, TRUE)) {
|
Chris@0
|
104 return AccessResult::forbidden();
|
Chris@0
|
105 }
|
Chris@0
|
106
|
Chris@0
|
107 // If the field is configured to accept anonymous contact details - admins
|
Chris@0
|
108 // can edit name, homepage and mail. Anonymous users can also fill in the
|
Chris@0
|
109 // fields on comment creation.
|
Chris@0
|
110 if (in_array($field_definition->getName(), ['name', 'mail', 'homepage'], TRUE)) {
|
Chris@0
|
111 if (!$items) {
|
Chris@0
|
112 // We cannot make a decision about access to edit these fields if we
|
Chris@0
|
113 // don't have any items and therefore cannot determine the Comment
|
Chris@0
|
114 // entity. In this case we err on the side of caution and prevent edit
|
Chris@0
|
115 // access.
|
Chris@0
|
116 return AccessResult::forbidden();
|
Chris@0
|
117 }
|
Chris@0
|
118 $is_name = $field_definition->getName() === 'name';
|
Chris@0
|
119 /** @var \Drupal\comment\CommentInterface $entity */
|
Chris@0
|
120 $entity = $items->getEntity();
|
Chris@0
|
121 $commented_entity = $entity->getCommentedEntity();
|
Chris@0
|
122 $anonymous_contact = $commented_entity->get($entity->getFieldName())->getFieldDefinition()->getSetting('anonymous');
|
Chris@0
|
123 $admin_access = AccessResult::allowedIfHasPermission($account, 'administer comments');
|
Chris@0
|
124 $anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && ($anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT || $is_name) && $account->hasPermission('post comments'))
|
Chris@0
|
125 ->cachePerPermissions()
|
Chris@0
|
126 ->addCacheableDependency($entity)
|
Chris@0
|
127 ->addCacheableDependency($field_definition->getConfig($commented_entity->bundle()))
|
Chris@0
|
128 ->addCacheableDependency($commented_entity);
|
Chris@0
|
129 return $admin_access->orIf($anonymous_access);
|
Chris@0
|
130 }
|
Chris@0
|
131 }
|
Chris@0
|
132
|
Chris@0
|
133 if ($operation == 'view') {
|
Chris@0
|
134 // Nobody has access to the hostname.
|
Chris@0
|
135 if ($field_definition->getName() == 'hostname') {
|
Chris@0
|
136 return AccessResult::forbidden();
|
Chris@0
|
137 }
|
Chris@0
|
138 // The mail field is hidden from non-admins.
|
Chris@0
|
139 if ($field_definition->getName() == 'mail') {
|
Chris@0
|
140 return AccessResult::allowedIfHasPermission($account, 'administer comments');
|
Chris@0
|
141 }
|
Chris@0
|
142 }
|
Chris@0
|
143 return parent::checkFieldAccess($operation, $field_definition, $account, $items);
|
Chris@0
|
144 }
|
Chris@0
|
145
|
Chris@0
|
146 }
|