Skip to content

Instantly share code, notes, and snippets.

@briangonzalezmia
Created September 26, 2019 15:15
Show Gist options
  • Save briangonzalezmia/b2fca51abbe7ab719c8b6a57f0f0bffb to your computer and use it in GitHub Desktop.
Save briangonzalezmia/b2fca51abbe7ab719c8b6a57f0f0bffb to your computer and use it in GitHub Desktop.
<?php
namespace Drupal\comment_access_control_handler_extend;
use Drupal\comment\CommentAccessControlHandler;
use Drupal\comment\CommentInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\user\Entity\User;
use Drupal\Component\Serialization\Json;
class CommentAccessControlHandlerExtend extends CommentAccessControlHandler {
/**
* {@inheritdoc}
*/
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');
}
// Allow non-Admin user to specify their own id in a comment via REST / JSON:API
if ($field_definition->getName() === 'uid') {
$entity = $items->getEntity();
$fields = $entity->getFields();
$user_field = $fields['uid'][0]->getValue();
$user_id = implode($user_field);
$admin_access = AccessResult::allowedIfHasPermission($account, 'administer comments');
$user_access = AccessResult::allowedIf($account->id() === $user_id);
return $admin_access->orIf($user_access);
}
// 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',
];
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);
}
// 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';
/** @var \Drupal\comment\CommentInterface $entity */
$entity = $items->getEntity();
$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'))
->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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment