From 6758f115604d77c4cc2cb101963ccaef96f178da Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Wed, 20 May 2015 10:40:58 +0100 Subject: [PATCH] Issue #2475263 by LKS90, Berdir: Remove Role::postSave() method --- core/modules/comment/comment.routing.yml | 2 +- .../src/Controller/CommentController.php | 84 +++++++++++-------- .../CommentDefaultFormatter.php | 2 +- .../src/Tests/CommentAnonymousTest.php | 13 +-- .../src/Tests/CommentInterfaceTest.php | 6 +- .../comment/src/Tests/CommentNonNodeTest.php | 4 +- core/modules/user/src/Entity/Role.php | 10 --- 7 files changed, 62 insertions(+), 59 deletions(-) diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml index fea8cc1e2c0..967cb3f087f 100644 --- a/core/modules/comment/comment.routing.yml +++ b/core/modules/comment/comment.routing.yml @@ -57,7 +57,7 @@ comment.reply: _title: 'Add new comment' pid: ~ requirements: - _access: 'TRUE' + _custom_access: '\Drupal\comment\Controller\CommentController::replyFormAccess' options: parameters: entity: diff --git a/core/modules/comment/src/Controller/CommentController.php b/core/modules/comment/src/Controller/CommentController.php index e1451255b5d..add53333117 100644 --- a/core/modules/comment/src/Controller/CommentController.php +++ b/core/modules/comment/src/Controller/CommentController.php @@ -10,6 +10,7 @@ namespace Drupal\comment\Controller; use Drupal\comment\CommentInterface; use Drupal\comment\CommentManagerInterface; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\Core\Access\AccessResult; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; @@ -185,9 +186,6 @@ class CommentController extends ControllerBase { * There are several cases that have to be handled, including: * - replies to comments * - replies to entities - * - attempts to reply to entities that can no longer accept comments - * - respecting access permissions ('access comments', 'post comments', - * etc.) * * @param \Symfony\Component\HttpFoundation\Request $request * The current request object. @@ -201,57 +199,24 @@ class CommentController extends ControllerBase { * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException * @return array|\Symfony\Component\HttpFoundation\RedirectResponse - * One of the following: * An associative array containing: * - An array for rendering the entity or parent comment. * - comment_entity: If the comment is a reply to the entity. * - comment_parent: If the comment is a reply to another comment. * - comment_form: The comment form as a renderable array. - * - A redirect response to current node: - * - If user is not authorized to post comments. - * - If parent comment doesn't belong to current entity. - * - If user is not authorized to view comments. - * - If current entity comments are disable. */ public function getReplyForm(Request $request, EntityInterface $entity, $field_name, $pid = NULL) { - // Check if entity and field exists. - $fields = $this->commentManager->getFields($entity->getEntityTypeId()); - if (empty($fields[$field_name])) { - throw new NotFoundHttpException(); - } - $account = $this->currentUser(); $uri = $entity->urlInfo()->setAbsolute(); $build = array(); - // Check if the user has the proper permissions. - if (!$account->hasPermission('post comments')) { - drupal_set_message($this->t('You are not authorized to post comments.'), 'error'); - return new RedirectResponse($uri->toString()); - } - // The user is not just previewing a comment. if ($request->request->get('op') != $this->t('Preview')) { - $status = $entity->{$field_name}->status; - if ($status != CommentItemInterface::OPEN) { - drupal_set_message($this->t("This discussion is closed: you can't post new comments."), 'error'); - return new RedirectResponse($uri->toString()); - } // $pid indicates that this is a reply to a comment. if ($pid) { - // Check if the user has the proper permissions. - if (!$account->hasPermission('access comments')) { - drupal_set_message($this->t('You are not authorized to view comments.'), 'error'); - return new RedirectResponse($uri->toString()); - } // Load the parent comment. $comment = $this->entityManager()->getStorage('comment')->load($pid); - // Check if the parent comment is published and belongs to the entity. - if (!$comment->isPublished() || ($comment->getCommentedEntityId() != $entity->id())) { - drupal_set_message($this->t('The comment you are replying to does not exist.'), 'error'); - return new RedirectResponse($uri->toString()); - } // Display the parent comment. $build['comment_parent'] = $this->entityManager()->getViewBuilder('comment')->view($comment); } @@ -283,6 +248,53 @@ class CommentController extends ControllerBase { return $build; } + /** + * Access check for the reply form. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity this comment belongs to. + * @param string $field_name + * The field_name to which the comment belongs. + * @param int $pid + * (optional) Some comments are replies to other comments. In those cases, + * $pid is the parent comment's comment ID. Defaults to NULL. + * + * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException + * @return \Drupal\Core\Access\AccessResultInterface + * An access result + */ + public function replyFormAccess(EntityInterface $entity, $field_name, $pid = NULL) { + // Check if entity and field exists. + $fields = $this->commentManager->getFields($entity->getEntityTypeId()); + if (empty($fields[$field_name])) { + throw new NotFoundHttpException(); + } + + $account = $this->currentUser(); + + // Check if the user has the proper permissions. + $access = AccessResult::allowedIfHasPermission($account, 'post comments'); + + $status = $entity->{$field_name}->status; + $access = $access->andIf(AccessResult::allowedIf($status == CommentItemInterface::OPEN) + ->cacheUntilEntityChanges($entity)); + + // $pid indicates that this is a reply to a comment. + if ($pid) { + // Check if the user has the proper permissions. + $access = $access->andIf(AccessResult::allowedIfHasPermission($account, 'access comments')); + + /// Load the parent comment. + $comment = $this->entityManager()->getStorage('comment')->load($pid); + // Check if the parent comment is published and belongs to the entity. + $access = $access->andIf(AccessResult::allowedIf($comment && $comment->isPublished() && $comment->getCommentedEntityId() == $entity->id())); + if ($comment) { + $access->cacheUntilEntityChanges($comment); + } + } + return $access; + } + /** * Returns a set of nodes' last read timestamps. * diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index 1bb8134c416..fbca55b2a60 100644 --- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -157,7 +157,7 @@ class CommentDefaultFormatter extends FormatterBase implements ContainerFactoryP // Unpublished comments are not included in // $entity->get($field_name)->comment_count, but unpublished comments // should display if the user is an administrator. - $elements['#cache']['contexts'][] = 'user.roles'; + $elements['#cache']['contexts'][] = 'user.permissions'; if ($this->currentUser->hasPermission('access comments') || $this->currentUser->hasPermission('administer comments')) { // This is a listing of Comment entities, so associate its list cache // tag for correct invalidation. diff --git a/core/modules/comment/src/Tests/CommentAnonymousTest.php b/core/modules/comment/src/Tests/CommentAnonymousTest.php index 49ad78c705d..ca12dde0e9a 100644 --- a/core/modules/comment/src/Tests/CommentAnonymousTest.php +++ b/core/modules/comment/src/Tests/CommentAnonymousTest.php @@ -122,6 +122,10 @@ class CommentAnonymousTest extends CommentTestBase { $this->assertNoRaw('comments[' . $anonymous_comment3->id() . ']', 'Comment was deleted.'); $this->drupalLogout(); + // Comment 3 was deleted. + $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment/' . $anonymous_comment3->id()); + $this->assertResponse(403); + // Reset. user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array( 'access comments' => FALSE, @@ -138,9 +142,7 @@ class CommentAnonymousTest extends CommentTestBase { // Attempt to view node-comment form while disallowed. $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); - $this->assertText('You are not authorized to post comments', 'Error attempting to post comment.'); - $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.'); - $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.'); + $this->assertResponse(403); user_role_change_permissions(RoleInterface::ANONYMOUS_ID, array( 'access comments' => TRUE, @@ -162,8 +164,7 @@ class CommentAnonymousTest extends CommentTestBase { $this->assertFieldByName('subject[0][value]', '', 'Subject field found.'); $this->assertFieldByName('comment_body[0][value]', '', 'Comment field found.'); - $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment/' . $anonymous_comment3->id()); - $this->assertText('You are not authorized to view comments', 'Error attempting to post reply.'); - $this->assertNoText($author_name, 'Comment not displayed.'); + $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment/' . $anonymous_comment2->id()); + $this->assertResponse(403); } } diff --git a/core/modules/comment/src/Tests/CommentInterfaceTest.php b/core/modules/comment/src/Tests/CommentInterfaceTest.php index 85e2c257c26..6e97e6efb7a 100644 --- a/core/modules/comment/src/Tests/CommentInterfaceTest.php +++ b/core/modules/comment/src/Tests/CommentInterfaceTest.php @@ -155,20 +155,20 @@ class CommentInterfaceTest extends CommentTestBase { $reply_loaded->setPublished(FALSE); $reply_loaded->save(); $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment/' . $reply_loaded->id()); - $this->assertText(t('The comment you are replying to does not exist.'), 'Replying to an unpublished comment'); + $this->assertResponse(403); // Attempt to post to node with comments disabled. $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => array(array('status' => CommentItemInterface::HIDDEN)))); $this->assertTrue($this->node, 'Article node created.'); $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); - $this->assertText('This discussion is closed', 'Posting to node with comments disabled'); + $this->assertResponse(403); $this->assertNoField('edit-comment', 'Comment body field found.'); // Attempt to post to node with read-only comments. $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => array(array('status' => CommentItemInterface::CLOSED)))); $this->assertTrue($this->node, 'Article node created.'); $this->drupalGet('comment/reply/node/' . $this->node->id() . '/comment'); - $this->assertText('This discussion is closed', 'Posting to node with comments read-only'); + $this->assertResponse(403); $this->assertNoField('edit-comment', 'Comment body field found.'); // Attempt to post to node with comments enabled (check field names etc). diff --git a/core/modules/comment/src/Tests/CommentNonNodeTest.php b/core/modules/comment/src/Tests/CommentNonNodeTest.php index d3cd0896b45..a7f7918de27 100644 --- a/core/modules/comment/src/Tests/CommentNonNodeTest.php +++ b/core/modules/comment/src/Tests/CommentNonNodeTest.php @@ -344,7 +344,7 @@ class CommentNonNodeTest extends WebTestBase { // Attempt to view test entity comment form while disallowed. $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment'); - $this->assertText('You are not authorized to post comments', 'Error attempting to post comment.'); + $this->assertResponse(403); $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.'); $this->assertNoFieldByName('comment_body[0][value]', '', 'Comment field not found.'); @@ -376,7 +376,7 @@ class CommentNonNodeTest extends WebTestBase { $this->assertFieldByName('comment_body[0][value]', '', 'Comment field found.'); $this->drupalGet('comment/reply/entity_test/' . $this->entity->id() . '/comment/' . $comment1->id()); - $this->assertText('You are not authorized to view comments'); + $this->assertResponse(403); $this->assertNoText($comment1->getSubject(), 'Comment not displayed.'); // Test comment field widget changes. diff --git a/core/modules/user/src/Entity/Role.php b/core/modules/user/src/Entity/Role.php index b997e69b83b..930c04a5be5 100644 --- a/core/modules/user/src/Entity/Role.php +++ b/core/modules/user/src/Entity/Role.php @@ -186,14 +186,4 @@ class Role extends ConfigEntityBase implements RoleInterface { } } - /** - * {@inheritdoc} - */ - public function postSave(EntityStorageInterface $storage, $update = TRUE) { - parent::postSave($storage, $update); - - // Clear render cache. - entity_render_cache_clear(); - } - }