diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index bd9c107..09543e7 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -294,7 +294,8 @@ function comment_menu() { 'title' => 'Delete', 'page callback' => 'comment_confirm_delete_page', 'page arguments' => array(1), - 'access arguments' => array('administer comments'), + 'access callback' => 'comment_delete_access', + 'access arguments' => array(1), 'type' => MENU_LOCAL_TASK, 'file' => 'comment.admin.inc', 'weight' => 2, @@ -438,6 +439,9 @@ function comment_permission() { 'edit own comments' => array( 'title' => t('Edit own comments'), ), + 'delete own comments' => array( + 'title' => t('Delete your own unreplied comments'), + ), ); } @@ -1124,6 +1128,13 @@ function comment_links(Comment $comment, Node $node) { 'html' => TRUE, ); } + if (user_access('delete own comments') && comment_delete_access($comment->cid)) { + $links['comment-delete'] = array( + 'title' => t('delete'), + 'href' => "comment/$comment->cid/delete", + 'html' => TRUE, + ); + } $links['comment-reply'] = array( 'title' => t('reply'), 'href' => "comment/reply/$comment->nid/$comment->cid", @@ -1486,8 +1497,9 @@ function comment_user_predelete($account) { * The comment object. * * @return - * TRUE if the current user has acces to the comment, FALSE otherwise. + * TRUE if the current user has access to the comment, FALSE otherwise. */ + function comment_access($op, Comment $comment) { global $user; @@ -1497,6 +1509,50 @@ function comment_access($op, Comment $comment) { } /** + * Determines whether the current user has permissions to delete a comment. + * + * Authenticated users with 'delete own comments' permission can delete their + * comments if they have not been replied to. + * + * @param $cid + * The comment id. + * + * @return + * TRUE if the current user have access to delete his comment, FALSE otherwise. + */ + +function comment_delete_access($cid) { + global $user; + $comment = comment_load($cid); + + if ((user_access('administer comments')) || ($user->uid && $user->uid == $comment->uid && user_access('delete own comments') && user_access('post comments') && !comment_has_reply($comment->nid))) { + return TRUE; + } + elseif ($user->uid && $user->uid == $comment->uid && $comment->status == COMMENT_PUBLISHED && user_access('delete own comments') && user_access('post comments') && !comment_has_reply($comment->nid)) { + return TRUE; + } + else { + return FALSE; + } +} + +/** + * Determines whether a comment has replies. + * + * @param $nid + * The node id. + * + * @return + * TRUE if comment has replies, FALSE otherwise. + * + */ + +function comment_has_reply($nid) { + $replies = db_query('SELECT COUNT(nid) FROM {comment} WHERE nid = :nid', array(':nid' => $nid))->fetchField(); + return $replies > 1 ? TRUE : FALSE; +} + +/** * Accepts a submission of new or changed comment content. * * @param Drupal\comment\Comment $comment diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php index e122141..276ddd1 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php @@ -168,9 +168,78 @@ class CommentInterfaceTest extends CommentTestBase { $this->drupalGet('node/' . $this->node->nid); $form_comment = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); $this->assertTrue($this->commentExists($form_comment), t('Form comment found.')); + $this->drupalLogout(); - // Disable comment form on node page. + // Testing delete own comments. + // Create user to verify if they can delete own comments. + // We add replies with existing web_user. + // User #1 can post comment and delete own comments if unreplied. + $this->user1 = $this->drupalCreateUser(array('access comments', 'post comments', 'create page content', 'edit own comments', 'delete own comments')); + $this->drupalLogin($this->user1); + // Create a node and a comment . + $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN)); + $this->assertTrue($this->node, t('Page node created.')); + $subject_text = $this->randomName(); + $comment_text = $this->randomName(); + $comment = $this->postComment($this->node, $comment_text, $subject_text); + $comment_loaded = comment_load($comment->id); + $this->assertTrue($this->commentExists($comment), t('Comment found.')); + $this->drupalGet('node/'. $this->node->nid); + $this->assertLink('reply', 0, 'The reply link appears on the page'); + $this->assertLink('delete', 0, 'The delete link appears on the page'); + $this->drupalLogout(); + + // Add reply to the comment with web_user. + $this->drupalLogin($this->web_user); + $this->drupalGet('comment/reply/' . $this->node->nid . '/' . $comment->id); + $this->assertText($subject_text, t('Individual comment-reply subject found.')); + $this->assertText($comment_text, t('Individual comment-reply body found.')); + $reply = $this->postComment(NULL, $this->randomName(), '', TRUE); + $reply_loaded = comment_load($reply->id); + $this->assertTrue($this->commentExists($reply, TRUE), t('Reply found.')); + $this->drupalLogout(); + + // Verify that the delete link doesn't appear. + $this->drupalLogin($this->user1); + $this->drupalGet('node/'. $this->node->nid); + $this->assertLink('reply', 0, 'The reply link appears on the page'); + $this->assertNoLink('delete', 'The delete link doesn\'t appear.'); $this->drupalLogout(); + + // Delete the reply. + $this->drupalLogin($this->admin_user); + $this->drupalPost('comment/' . $reply->id . '/delete', array(), t('Delete')); + $this->assertText(t('The comment and all its replies have been deleted.'), t('Comment deleted.')); + $this->drupalLogout(); + + // Verify that the delete link appears.We can only delete unreplied comments. + $this->drupalLogin($this->user1); + $this->drupalGet('node/'. $this->node->nid); + $this->assertLink('reply', 0, 'The reply link appears on the page'); + $this->assertLink('delete', 0, 'The delete link appears.'); + $this->deleteComment($comment); + $this->drupalLogout(); + + // Create a node with web_user whom can post comments but can't delete own comments. + $this->drupalLogin($this->web_user); + // Create a node and a comment . + $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'comment' => COMMENT_NODE_OPEN)); + $this->assertTrue($this->node, t('Page node created.')); + $subject_text = $this->randomName(); + $comment_text = $this->randomName(); + $comment = $this->postComment($this->node, $comment_text, $subject_text); + $comment_loaded = comment_load($comment->id); + $this->assertTrue($this->commentExists($comment), t('Comment found.')); + $this->drupalGet('node/'. $this->node->nid); + $this->assertLink('reply', 0, 'The reply link appears on the page'); + $this->assertNoLink('delete', 'The delete link doesn\'t appear.'); + // Delete link doesn't appear and also verify that the user can't delete the comment. + $this->drupalGet('comment/' . $comment->id . '/delete'); + $this->assertText(t('Access denied'), t('Found the default 403 page')); + $this->assertResponse(403); + $this->drupalLogout(); + + // Disable comment form on node page. $this->drupalLogin($this->admin_user); $this->setCommentForm(FALSE); }