I am trying to extend access to comments based on the entity they are attached to.
I have created permissions in my permissions.yml file as following.
view user comments:
title: 'View comments attached to Users'
Then in my .module
file, in a hook_entity_type_build()
I have changed the Handler Class for the Comment entity with my custom one.
/**
* Implements hook_entity_type_build().
*/
function MY_CUSTOM_MODULE_entity_type_build(array &$entity_types) {
// I need this so I can alter the Comment Permisions with my custom ones.
if (isset($entity_types('comment'))) {
$entity_types('comment')->setHandlerClass('access', 'DrupalMY_CUSTOM_MODULEAccessCustomCommentAccessControlHandler');
}
}
My custom class extends the initial Handler and I am only overwriting what I need.
/**
* Adds a custom access handler for Comments.
*/
class CustomCommentAccessControlHandler extends CommentAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
DELETE
, UPDATE
and CREATE/REPLY
work exactly how I wish and how I’ve overwritten them but my issue is with VIEW
.
I have defined my view
case in a switch in the checkAccess
function like this (please note that the other cases in my switch behave as desired):
case 'view':
// View comments depending on the parent entity.
$canViewUserCom = $account->hasPermission('view user comments');
// If parent entity is user.
if ($entityType == 'user') {
$access = AccessResult::allowedIf($canViewUserCom)
->cachePerPermissions()
->addCacheableDependency($entity);
// Set reason when forbidden or neutral.
if (!$access->isAllowed()) {
$access->setReason("The 'view user comments' permission is required.");
}
}
I have debugged the $access
variable and it returns what it needs to. I have tried to forbid access completely just to debug and it does not seem to overwrite the ‘access comments’ permission not matter what I do.
I have debugged further and I got to this class in the comment module.
namespace Drupalcomment;
use DrupalCoreAccessAccessResult;
use DrupalCoreFieldFieldItemList;
use DrupalCoreSessionAccountInterface;
/**
* Defines a item list class for comment fields.
*/
class CommentFieldItemList extends FieldItemList {
Inside this class, there is a function called access()
which looks like this:
/**
* {@inheritdoc}
*/
public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
if ($operation === 'edit') {
// Only users with administer comments permission can edit the comment
// status field.
$result = AccessResult::allowedIfHasPermission($account ?: Drupal::currentUser(), 'administer comments');
return $return_as_object ? $result : $result->isAllowed();
}
if ($operation === 'view') {
// Only users with "post comments" or "access comments" permission can
// view the field value. The formatter,
// DrupalcommentPluginFieldFieldFormatterCommentDefaultFormatter,
// takes care of showing the thread and form based on individual
// permissions, so if a user only has ‘post comments’ access, only the
// form will be shown and not the comments.
$result = AccessResult::allowedIfHasPermission($account ?: Drupal::currentUser(), 'access comments')
->orIf(AccessResult::allowedIfHasPermission($account ?: Drupal::currentUser(), 'post comments'));
// $result = AccessResult::forbidden(); // -> I HAVE ADDED THIS TO TEST
return $return_as_object ? $result : $result->isAllowed();
}
return parent::access($operation, $account, $return_as_object);
}
If I remove/overwrite line 59/60 (or in this case, I overwrite the return of the function with another access opinion), I get my desired functionality. Now, the problem is that it is not ok to edit code inside core as it will be lost with every update. How do I hook into this class in order to rewrite the access
function? Or, is there perhaps another approach for the functionality I need (view comments based on which entity they are attached to)?