diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -25,7 +25,6 @@ use Drupal\field\FieldConfigInterface; use Drupal\field\FieldStorageConfigInterface; use Drupal\node\NodeInterface; -use Drupal\user\RoleInterface; use Drupal\user\UserInterface; /** @@ -354,48 +353,26 @@ * Implements hook_node_update_index(). */ function comment_node_update_index(EntityInterface $node) { - $index_comments = &drupal_static(__FUNCTION__); - - if ($index_comments === NULL) { - // Do not index in the following three cases: - // 1. 'Authenticated user' can search content but can't access comments. - // 2. 'Anonymous user' can search content but can't access comments. - // 3. Any role can search content but can't access comments and access - // comments is not granted by the 'authenticated user' role. In this case - // all users might have both permissions from various roles but it is also - // possible to set up a user to have only search content and so a user - // edit could change the security situation so it is not safe to index the - // comments. - $index_comments = TRUE; - $roles = \Drupal::entityTypeManager()->getStorage('user_role')->loadMultiple(); - $authenticated_can_access = $roles[RoleInterface::AUTHENTICATED_ID]->hasPermission('access comments'); - foreach ($roles as $rid => $role) { - if ($role->hasPermission('search content') && !$role->hasPermission('access comments')) { - if ($rid == RoleInterface::AUTHENTICATED_ID || $rid == RoleInterface::ANONYMOUS_ID || !$authenticated_can_access) { - $index_comments = FALSE; - break; - } - } - } - } $build = []; + $manager = \Drupal::service('comment.manager'); - if ($index_comments) { - foreach (\Drupal::service('comment.manager')->getFields('node') as $field_name => $info) { - // Skip fields that entity does not have. - if (!$node->hasField($field_name)) { - continue; - } - $field_definition = $node->getFieldDefinition($field_name); - $mode = $field_definition->getSetting('default_mode'); - $comments_per_page = $field_definition->getSetting('per_page'); - if ($node->get($field_name)->status) { - $comments = \Drupal::entityTypeManager()->getStorage('comment') - ->loadThread($node, $field_name, $mode, $comments_per_page); - if ($comments) { - $build[] = \Drupal::entityTypeManager()->getViewBuilder('comment')->viewMultiple($comments); - } + foreach ($manager->getFields('node') as $field_name => $info) { + // Skip fields that entity does not have. + if (!$node->hasField($field_name)) { + continue; + } + if (!$manager->isIndexingAvailable($node, $field_name)) { + continue; + } + $field_definition = $node->getFieldDefinition($field_name); + $mode = $field_definition->getSetting('default_mode'); + $comments_per_page = $field_definition->getSetting('per_page'); + if ($node->get($field_name)->status) { + $comments = \Drupal::entityManager()->getStorage('comment') + ->loadThread($node, $field_name, $mode, $comments_per_page); + if ($comments) { + $build[] = \Drupal::entityManager()->getViewBuilder('comment')->viewMultiple($comments); } } } @@ -428,8 +405,8 @@ } // Do not make a string if comments are hidden. $status = (int) $node->get($field_name)->status; - if ($status !== CommentItemInterface::HIDDEN) { - if ($status === CommentItemInterface::OPEN) { + if (\Drupal::currentUser()->hasPermission('access comments ' . $node->{$field_name}->getSetting('comment_type')) && $status != CommentItemInterface::HIDDEN) { + if ($status == CommentItemInterface::OPEN) { // At least one comment field is open. $open = TRUE; } diff --git a/core/modules/comment/comment.permissions.yml b/core/modules/comment/comment.permissions.yml --- a/core/modules/comment/comment.permissions.yml +++ b/core/modules/comment/comment.permissions.yml @@ -7,7 +7,13 @@ title: 'View comments' post comments: title: 'Post comments' +reply comments: + title: 'Reply comments' skip comment approval: title: 'Skip comment approval' edit own comments: title: 'Edit own comments' + +permission_callbacks: + - \Drupal\comment\CommentPermissions::commentTypePermissions + diff --git a/core/modules/comment/src/CommentAccessControlHandler.php b/core/modules/comment/src/CommentAccessControlHandler.php --- a/core/modules/comment/src/CommentAccessControlHandler.php +++ b/core/modules/comment/src/CommentAccessControlHandler.php @@ -36,7 +36,7 @@ switch ($operation) { case 'view': - $access_result = AccessResult::allowedIf($account->hasPermission('access comments') && $entity->isPublished())->cachePerPermissions()->addCacheableDependency($entity) + $access_result = AccessResult::allowedIf($account->hasPermission('access comments ' . $entity->bundle()) && $entity->isPublished())->cachePerPermissions()->addCacheableDependency($entity) ->andIf($entity->getCommentedEntity()->access($operation, $account, TRUE)); if (!$access_result->isAllowed()) { $access_result->setReason("The 'access comments' permission is required and the comment must be published."); @@ -45,7 +45,7 @@ return $access_result; case 'update': - $access_result = AccessResult::allowedIf($account->id() && $account->id() == $entity->getOwnerId() && $entity->isPublished() && $account->hasPermission('edit own comments')) + $access_result = AccessResult::allowedIf($account->id() && $account->id() == $entity->getOwnerId() && $entity->isPublished() && $account->hasPermission('edit own comments ' . $entity->bundle())) ->cachePerPermissions()->cachePerUser()->addCacheableDependency($entity); if (!$access_result->isAllowed()) { $access_result->setReason("The 'edit own comments' permission is required, the user must be the comment author, and the comment must be published."); @@ -62,7 +62,7 @@ * {@inheritdoc} */ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { - return AccessResult::allowedIfHasPermission($account, 'post comments'); + return AccessResult::allowedIfHasPermission($account, 'post comments ' . $entity_bundle); } /** @@ -100,7 +100,7 @@ ]; if ($items && ($entity = $items->getEntity()) && $entity->isNew() && in_array($field_definition->getName(), $create_only_fields, TRUE)) { // We are creating a new comment, user can edit create only fields. - return AccessResult::allowedIfHasPermission($account, 'post comments')->addCacheableDependency($entity); + return AccessResult::allowedIfHasPermission($account, 'post comments ' . $entity->bundle())->addCacheableDependency($entity); } // We are editing an existing comment - create only fields are now read // only. @@ -126,7 +126,7 @@ $commented_entity = $entity->getCommentedEntity(); $anonymous_contact = $commented_entity->get($entity->getFieldName())->getFieldDefinition()->getSetting('anonymous'); $admin_access = AccessResult::allowedIfHasPermission($account, 'administer comments'); - $anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && ($anonymous_contact != CommentInterface::ANONYMOUS_MAYNOT_CONTACT || $is_name) && $account->hasPermission('post comments')) + $anonymous_access = AccessResult::allowedIf($entity->isNew() && $account->isAnonymous() && ($anonymous_contact != COMMENT_ANONYMOUS_MAYNOT_CONTACT || $is_name) && $account->hasPermission('post comments ' . $entity->bundle())) ->cachePerPermissions() ->addCacheableDependency($entity) ->addCacheableDependency($field_definition->getConfig($commented_entity->bundle())) diff --git a/core/modules/comment/src/CommentFieldItemList.php b/core/modules/comment/src/CommentFieldItemList.php --- a/core/modules/comment/src/CommentFieldItemList.php +++ b/core/modules/comment/src/CommentFieldItemList.php @@ -49,7 +49,8 @@ if ($operation === 'edit') { // Only users with administer comments permission can edit the comment // status field. - $result = AccessResult::allowedIfHasPermission($account, 'administer comments'); + $result = AccessResult::allowedIfHasPermission($account ?: \Drupal::currentUser(), 'access comments ' . $this->getSetting('comment_type')) + ->orIf(AccessResult::allowedIfHasPermission($account ?: \Drupal::currentUser(), 'post comments ' . $this->getSetting('comment_type'))); return $return_as_object ? $result : $result->isAllowed(); } if ($operation === 'view') { diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php --- a/core/modules/comment/src/CommentForm.php +++ b/core/modules/comment/src/CommentForm.php @@ -151,7 +151,7 @@ } } else { - $status = ($this->currentUser->hasPermission('skip comment approval') ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED); + $status = ($this->currentUser->hasPermission('skip comment approval ' . $comment->bundle()) ? CommentInterface::PUBLISHED : CommentInterface::NOT_PUBLISHED); } $date = ''; @@ -376,7 +376,7 @@ $uri = $entity->toUrl(); $logger = $this->logger('comment'); - if ($comment->access('create', $this->currentUser) && ($this->currentUser->hasPermission('administer comments') || $entity->{$field_name}->status == CommentItemInterface::OPEN)) { + if ($this->currentUser->hasPermission('post comments ' . $comment->bundle()) && ($this->currentUser->hasPermission('administer comments') || $entity->{$field_name}->status == CommentItemInterface::OPEN)) { $comment->save(); $form_state->setValue('cid', $comment->id()); diff --git a/core/modules/comment/src/CommentLazyBuilders.php b/core/modules/comment/src/CommentLazyBuilders.php --- a/core/modules/comment/src/CommentLazyBuilders.php +++ b/core/modules/comment/src/CommentLazyBuilders.php @@ -168,36 +168,42 @@ $status = $commented_entity->get($entity->getFieldName())->status; if ($status == CommentItemInterface::OPEN) { - if ($entity->access('delete')) { + $delete_url = $entity->toUrl('delete-form'); + if ($delete_url->access()) { $links['comment-delete'] = [ 'title' => t('Delete'), - 'url' => $entity->toUrl('delete-form'), + 'url' => $delete_url, ]; } - if ($entity->access('update')) { + $update_url = $entity->toUrl('edit-form'); + if ($update_url->access()) { $links['comment-edit'] = [ 'title' => t('Edit'), - 'url' => $entity->toUrl('edit-form'), + 'url' => $update_url, ]; } $field_definition = $commented_entity->getFieldDefinition($entity->getFieldName()); - if ($entity->access('create') - && $field_definition->getSetting('default_mode') === CommentManagerInterface::COMMENT_MODE_THREADED) { - $links['comment-reply'] = [ - 'title' => t('Reply'), - 'url' => Url::fromRoute('comment.reply', [ - 'entity_type' => $entity->getCommentedEntityTypeId(), - 'entity' => $entity->getCommentedEntityId(), - 'field_name' => $entity->getFieldName(), - 'pid' => $entity->id(), - ]), + + $create_url = Url::fromRoute('comment.reply', [ + 'entity_type' => $entity->getCommentedEntityTypeId(), + 'entity' => $entity->getCommentedEntityId(), + 'field_name' => $entity->getFieldName(), + 'pid' => $entity->id(), + ]); + if ($create_url->access() + && $field_definition->getSetting('default_mode') === CommentManagerInterface::COMMENT_MODE_THREADED) { + $links['comment-reply'] = [ + 'title' => t('Reply'), + 'url' => $create_url, ]; } - if (!$entity->isPublished() && $entity->access('approve')) { + + $approve_url = Url::fromRoute('comment.approve', ['comment' => $entity->id()]); + if (!$entity->isPublished() && $approve_url->access()) { $links['comment-approve'] = [ 'title' => t('Approve'), - 'url' => Url::fromRoute('comment.approve', ['comment' => $entity->id()]), + 'url' => $approve_url, ]; } if (empty($links) && $this->currentUser->isAnonymous()) { diff --git a/core/modules/comment/src/CommentLinkBuilder.php b/core/modules/comment/src/CommentLinkBuilder.php --- a/core/modules/comment/src/CommentLinkBuilder.php +++ b/core/modules/comment/src/CommentLinkBuilder.php @@ -102,30 +102,37 @@ // Teaser view: display the number of comments that have been posted, // or a link to add new comments if the user has permission, the // entity is open to new comments, and there currently are none. - if ($field->comment_count > 0 && $field->access('view comment list', $this->currentUser)) { - $links['comment-comments'] = [ - 'title' => $this->formatPlural($field->comment_count, '1 comment', '@count comments'), - 'attributes' => ['title' => $this->t('Jump to the first comment.')], - 'fragment' => 'comments', - 'url' => $entity->toUrl(), - ]; - if ($this->moduleHandler->moduleExists('history')) { - $links['comment-new-comments'] = [ - 'title' => '', - 'url' => Url::fromRoute(''), - 'attributes' => [ - 'class' => 'hidden', - 'title' => $this->t('Jump to the first new comment.'), - 'data-history-node-last-comment-timestamp' => $field->last_comment_timestamp, - 'data-history-node-field-name' => $field_name, - ], - ]; + if ($this->currentUser->hasPermission('access comments ' . $field_definition->getSetting('comment_type'))) { + if (!empty($entity->get($field_name)->comment_count)) { + $links['comment-comments'] = [ + 'title' => $this->formatPlural($field->comment_count, '1 comment', '@count comments'), + 'attributes' => ['title' => $this->t('Jump to the first comment.')], + 'fragment' => 'comments', + 'url' => $entity->toUrl(), + ]; + if ($this->moduleHandler->moduleExists('history')) { + $links['comment-new-comments'] = [ + 'title' => '', + 'url' => Url::fromRoute(''), + 'attributes' => [ + 'class' => 'hidden', + 'title' => $this->t('Jump to the first new comment.'), + 'data-history-node-last-comment-timestamp' => $field->last_comment_timestamp, + 'data-history-node-field-name' => $field_name, + ], + ]; + } } } // Provide a link to new comment form. if ($commenting_status == CommentItemInterface::OPEN) { + $comment_form_url = Url::fromRoute('comment.reply', [ + 'entity_type' => $entity->getEntityTypeId(), + 'entity' => $entity->id(), + 'field_name' => $field_name, + ]); $comment_form_location = $field_definition->getSetting('form_location'); - if ($field->access('create', $this->currentUser)) { + if ($comment_form_url->access()) { $links['comment-add'] = [ 'title' => $this->t('Add new comment'), 'language' => $entity->language(), @@ -133,11 +140,7 @@ 'fragment' => 'comment-form', ]; if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) { - $links['comment-add']['url'] = Url::fromRoute('comment.reply', [ - 'entity_type' => $entity->getEntityTypeId(), - 'entity' => $entity->id(), - 'field_name' => $field_name, - ]); + $links['comment-add']['url'] = $comment_form_url; } else { $links['comment-add'] += ['url' => $entity->toUrl()]; @@ -156,23 +159,22 @@ // comments. if ($commenting_status == CommentItemInterface::OPEN) { $comment_form_location = $field_definition->getSetting('form_location'); - if ($field->access('create', $this->currentUser)) { + $comment_form_url = Url::fromRoute('comment.reply', [ + 'entity_type' => $entity->getEntityTypeId(), + 'entity' => $entity->id(), + 'field_name' => $field_name, + ]); + if ($comment_form_url->access()) { // Show the "post comment" link if the form is on another page, or // if there are existing comments that the link will skip past. - $separate_form_location = $comment_form_location === CommentItemInterface::FORM_SEPARATE_PAGE; - $existing_comments = $field->comment_count > 0 && $field->access('view comment list', $this->currentUser); - if ($separate_form_location || $existing_comments) { + if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE || (!empty($entity->get($field_name)->comment_count) && $this->currentUser->hasPermission('access comments ' . $field_definition->getSetting('comment_type')))) { $links['comment-add'] = [ 'title' => $this->t('Add new comment'), 'attributes' => ['title' => $this->t('Share your thoughts and opinions.')], 'fragment' => 'comment-form', ]; if ($comment_form_location == CommentItemInterface::FORM_SEPARATE_PAGE) { - $links['comment-add']['url'] = Url::fromRoute('comment.reply', [ - 'entity_type' => $entity->getEntityTypeId(), - 'entity' => $entity->id(), - 'field_name' => $field_name, - ]); + $links['comment-add']['url'] = $comment_form_url; } else { $links['comment-add']['url'] = $entity->toUrl(); diff --git a/core/modules/comment/src/CommentManager.php b/core/modules/comment/src/CommentManager.php --- a/core/modules/comment/src/CommentManager.php +++ b/core/modules/comment/src/CommentManager.php @@ -17,6 +17,7 @@ use Drupal\Core\Url; use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\Entity\FieldConfig; +use Drupal\user\RoleInterface; use Drupal\user\UserInterface; /** @@ -74,6 +75,13 @@ */ protected $currentUser; + /** + * Comment types indexing permissions. + * + * @var array + */ + protected $typesIndexPermissions = []; + /** * Construct the CommentManager object. * @@ -166,7 +174,10 @@ UserInterface::AUTHENTICATED_ROLE, ], ]); - $this->authenticatedCanPostComments = $field->access('create', $dummy_authenticated_user); + $this->authenticatedCanPostComments = $this->entityTypeManager + ->getStorage('user_role') + ->load(RoleInterface::AUTHENTICATED_ID) + ->hasPermission('post comments ' . $entity->{$field_name}->getSetting('comment_type')); } if ($this->authenticatedCanPostComments) { @@ -244,4 +255,38 @@ return FALSE; } + /** + * {@inheritdoc} + */ + public function isIndexingAvailable(EntityInterface $entity, $field_name) { + $comment_type = $entity->{$field_name}->getSetting('comment_type'); + + if (array_key_exists($comment_type, $this->typesIndexPermissions)) { + return $this->typesIndexPermissions[$comment_type]; + } + + // Do not index in the following three cases: + // 1. 'Authenticated user' can search content but can't access comments. + // 2. 'Anonymous user' can search content but can't access comments. + // 3. Any role can search content but can't access comments and access + // comments is not granted by the 'authenticated user' role. In this case + // all users might have both permissions from various roles but it is also + // possible to set up a user to have only search content and so a user + // edit could change the security situation so it is not safe to index the + // comments. + $this->typesIndexPermissions[$comment_type] = TRUE; + $roles = $this->entityManager->getStorage('user_role')->loadMultiple(); + $authenticated_can_access = $roles[RoleInterface::AUTHENTICATED_ID]->hasPermission('access comments ' . $comment_type); + foreach ($roles as $rid => $role) { + if ($role->hasPermission('search content') && !$role->hasPermission('access comments ' . $comment_type)) { + if ($rid == RoleInterface::AUTHENTICATED_ID || $rid == RoleInterface::ANONYMOUS_ID || !$authenticated_can_access) { + $this->typesIndexPermissions[$comment_type] = FALSE; + break; + } + } + } + + return $this->typesIndexPermissions[$comment_type]; + } + } diff --git a/core/modules/comment/src/CommentManagerInterface.php b/core/modules/comment/src/CommentManagerInterface.php --- a/core/modules/comment/src/CommentManagerInterface.php +++ b/core/modules/comment/src/CommentManagerInterface.php @@ -75,4 +75,17 @@ */ public function getCountNewComments(EntityInterface $entity, $field_name = NULL, $timestamp = 0); + /** + * Check is comments indexing available for requested entity field. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * Entity object to check. + * @param string $field_name + * Field machine name. + * + * @return bool + * Result of check. + */ + public function isIndexingAvailable(EntityInterface $entity, $field_name); + } diff --git a/core/modules/comment/src/CommentPermissions.php b/core/modules/comment/src/CommentPermissions.php new file mode 100644 index 0000000000..b65b278a83 --- /dev/null +++ b/core/modules/comment/src/CommentPermissions.php @@ -0,0 +1,63 @@ +buildPermissions($type); + } + return $perms; + } + + /** + * Returns a list of comment permissions for a given comment type. + * + * @param \Drupal\comment\Entity\CommentType $type + * The comment type. + * + * @return array + * An associative array of permission names and descriptions. + */ + protected function buildPermissions(CommentType $type) { + $type_id = $type->id(); + $args = ['%type_name' => $type->label()]; + + return [ + 'access comments ' . $type_id => [ + 'title' => $this->t('%type_name: View comments', $args), + ], + 'post comments ' . $type_id => [ + 'title' => $this->t('%type_name: Post comments', $args), + ], + 'reply comments ' . $type_id => [ + 'title' => $this->t('%type_name: Reply comments', $args), + ], + 'skip comment approval ' . $type_id => [ + 'title' => $this->t('%type_name: Skip comment approval', $args), + ], + 'edit own comments ' . $type_id => [ + 'title' => $this->t('%type_name: Edit own comments', $args), + ], + ]; + } + +} diff --git a/core/modules/comment/src/Controller/CommentController.php b/core/modules/comment/src/Controller/CommentController.php --- a/core/modules/comment/src/Controller/CommentController.php +++ b/core/modules/comment/src/Controller/CommentController.php @@ -230,17 +230,36 @@ public function getReplyForm(Request $request, EntityInterface $entity, $field_name, $pid = NULL) { $account = $this->currentUser(); $build = []; + // Check if the user has the proper permissions. + $comment_type = $entity->{$field_name}->getSetting('comment_type'); // The user is not just previewing a comment. if ($request->request->get('op') != $this->t('Preview')) { + // If commenting is open on the entity. + if (!$pid) { + $access = AccessResult::allowedIfHasPermission($account, 'post comments ' . $comment_type); + $status = $entity->{$field_name}->status; + $access->andIf(AccessResult::allowedIf($status == CommentItemInterface::OPEN) + ->addCacheableDependency($entity)) + // And if user has access to the host entity. + ->andIf(AccessResult::allowedIf($entity->access('view'))); + } // $pid indicates that this is a reply to a comment. - if ($pid) { + else { + // Check if the user has the proper permissions. + AccessResult::allowedIfHasPermission($account, 'reply comments ' . $comment_type); + // Load the parent comment. - $comment = $this->entityTypeManager()->getStorage('comment')->load($pid); + $comment = $this->entityTypeManager() + ->getStorage('comment') + ->load($pid); // Display the parent comment. - $build['comment_parent'] = $this->entityTypeManager()->getViewBuilder('comment')->view($comment); + $build['comment_parent'] = $this->entityTypeManager() + ->getViewBuilder('comment') + ->view($comment); } + } // The comment is in response to an entity. elseif ($entity->access('view', $account)) { @@ -252,7 +271,6 @@ $build['commented_entity'] = $this->entityTypeManager()->getViewBuilder($entity->getEntityTypeId())->view($entity, 'full'); unset($build['commented_entity']['#cache']); } - } else { $build['#title'] = $this->t('Preview comment'); } diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php --- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -164,7 +164,7 @@ // $entity->get($field_name)->comment_count, but unpublished comments // should display if the user is an administrator. $elements['#cache']['contexts'][] = 'user.permissions'; - if ($items->access('view comment list', $this->currentUser) || $this->currentUser->hasPermission('administer comments')) { + if ($this->currentUser->hasPermission('access comments ' . $this->getFieldSetting('comment_type')) || $this->currentUser->hasPermission('administer comments')) { $output['comments'] = []; if ($items->comment_count || $this->currentUser->hasPermission('administer comments')) { @@ -194,7 +194,7 @@ if ($status == CommentItemInterface::OPEN && $comment_settings['form_location'] == CommentItemInterface::FORM_BELOW && $this->viewMode != 'print') { // Only show the add comment form if the user has permission. $elements['#cache']['contexts'][] = 'user.roles'; - if ($items->access('create', $this->currentUser)) { + if ($this->currentUser->hasPermission('post comments ' . $this->getFieldSetting('comment_type'))) { $output['comment_form'] = [ '#lazy_builder' => [ 'comment.lazy_builders:renderForm', diff --git a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php --- a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php +++ b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php @@ -134,7 +134,7 @@ CommentInterface::ANONYMOUS_MAY_CONTACT => $this->t('Anonymous posters may leave their contact information'), CommentInterface::ANONYMOUS_MUST_CONTACT => $this->t('Anonymous posters must leave their contact information'), ], - '#access' => $anonymous_user_access, + '#access' => $anonymous_user->hasPermission('post comments ' . $this->getSetting('comment_type')), ]; $element['form_location'] = [ '#type' => 'checkbox',