function CommentAccessControlHandler::checkFieldAccess

Same name and namespace in other branches
  1. 9 core/modules/comment/src/CommentAccessControlHandler.php \Drupal\comment\CommentAccessControlHandler::checkFieldAccess()
  2. 8.9.x core/modules/comment/src/CommentAccessControlHandler.php \Drupal\comment\CommentAccessControlHandler::checkFieldAccess()
  3. 10 core/modules/comment/src/CommentAccessControlHandler.php \Drupal\comment\CommentAccessControlHandler::checkFieldAccess()

Overrides EntityAccessControlHandler::checkFieldAccess

File

core/modules/comment/src/CommentAccessControlHandler.php, line 72

Class

CommentAccessControlHandler
Defines the access control handler for the comment entity type.

Namespace

Drupal\comment

Code

protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, ?FieldItemListInterface $items = NULL) {
    if ($operation == 'edit') {
        // Only users with the "administer comments" permission can edit
        // administrative fields.
        $administrative_fields = [
            'uid',
            'status',
            'created',
            'date',
        ];
        if (in_array($field_definition->getName(), $administrative_fields, TRUE)) {
            return AccessResult::allowedIfHasPermission($account, 'administer comments');
        }
        // No user can change read-only fields.
        $read_only_fields = [
            'hostname',
            'changed',
            'cid',
            'thread',
        ];
        // These fields can be edited during comment creation.
        $create_only_fields = [
            'comment_type',
            'uuid',
            'entity_id',
            'entity_type',
            'field_name',
            'pid',
        ];
        
        /** @var \Drupal\comment\CommentInterface|null $entity */
        $entity = $items ? $items->getEntity() : NULL;
        $commented_entity = $entity ? $entity->getCommentedEntity() : NULL;
        if ($entity && $entity->isNew() && in_array($field_definition->getName(), $create_only_fields, TRUE)) {
            $access_result = AccessResult::allowedIfHasPermission($account, 'post comments')->addCacheableDependency($entity);
            $comment_field_name = $entity->get('field_name')->value;
            if ($commented_entity && $comment_field_name) {
                // We are creating a new comment, user can edit create only fields if
                // commenting is open.
                $commenting_status = (int) $commented_entity->get($comment_field_name)->status;
                $access_result = $access_result->andIf(AccessResult::allowedIf($commenting_status !== CommentItemInterface::CLOSED))
                    ->addCacheableDependency($commented_entity);
            }
            return $access_result;
        }
        // We are editing an existing comment - create only fields are now read
        // only.
        $read_only_fields = array_merge($read_only_fields, $create_only_fields);
        if (in_array($field_definition->getName(), $read_only_fields, TRUE)) {
            return AccessResult::forbidden();
        }
        // If the field is configured to accept anonymous contact details - admins
        // can edit name, homepage and mail. Anonymous users can also fill in the
        // fields on comment creation.
        if (in_array($field_definition->getName(), [
            'name',
            'mail',
            'homepage',
        ], TRUE)) {
            if (!$items) {
                // We cannot make a decision about access to edit these fields if we
                // don't have any items and therefore cannot determine the Comment
                // entity. In this case we err on the side of caution and prevent edit
                // access.
                return AccessResult::forbidden();
            }
            $is_name = $field_definition->getName() === 'name';
            $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'))
                ->cachePerPermissions()
                ->addCacheableDependency($entity)
                ->addCacheableDependency($field_definition->getConfig($commented_entity->bundle()))
                ->addCacheableDependency($commented_entity);
            return $admin_access->orIf($anonymous_access);
        }
    }
    if ($operation == 'view') {
        // Nobody has access to the hostname.
        if ($field_definition->getName() == 'hostname') {
            return AccessResult::forbidden();
        }
        // The mail field is hidden from non-admins.
        if ($field_definition->getName() == 'mail') {
            return AccessResult::allowedIfHasPermission($account, 'administer comments');
        }
    }
    return parent::checkFieldAccess($operation, $field_definition, $account, $items);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.