Commit 26697707 authored by catch's avatar catch

Issue #1862754 by dawehner, Berdir: Implement entity access API for comments.

parent fd7f1183
......@@ -262,17 +262,14 @@ function comment_multiple_delete_confirm_submit($form, &$form_state) {
/**
* Page callback: Shows a confirmation page for comment deletions.
*
* @param $cid
* The ID of the comment that is about to be deleted.
* @param \Drupal\comment\Plugin\Core\Entity\Comment $comment
* The comment entity that is about to be deleted.
*
* @see comment_menu()
* @see comment_confirm_delete()
*/
function comment_confirm_delete_page($cid) {
if ($comment = comment_load($cid)) {
return drupal_get_form('comment_confirm_delete', $comment);
}
throw new NotFoundHttpException();
function comment_confirm_delete_page(Comment $comment) {
return drupal_get_form('comment_confirm_delete', $comment);
}
/**
......
......@@ -240,13 +240,14 @@ function comment_menu() {
'access arguments' => array('administer comments'),
'type' => MENU_LOCAL_TASK,
);
$items['comment/%'] = array(
$items['comment/%comment'] = array(
'title' => 'Comment permalink',
'page callback' => 'comment_permalink',
'page arguments' => array(1),
'access arguments' => array('access comments'),
'access callback' => 'entity_page_access',
'access arguments' => array(1, 'view'),
);
$items['comment/%/view'] = array(
$items['comment/%comment/view'] = array(
'title' => 'View comment',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
......@@ -256,23 +257,25 @@ function comment_menu() {
'title' => 'Edit',
'page callback' => 'comment_edit_page',
'page arguments' => array(1),
'access callback' => 'comment_access',
'access arguments' => array('edit', 1),
'access callback' => 'entity_page_access',
'access arguments' => array(1, 'update'),
'type' => MENU_LOCAL_TASK,
);
$items['comment/%/approve'] = array(
$items['comment/%comment/approve'] = array(
'title' => 'Approve',
'page callback' => 'comment_approve',
'page arguments' => array(1),
'access arguments' => array('administer comments'),
'access callback' => 'entity_page_access',
'access arguments' => array(1, 'approve'),
'file' => 'comment.pages.inc',
'weight' => 10,
);
$items['comment/%/delete'] = array(
$items['comment/%comment/delete'] = array(
'title' => 'Delete',
'page callback' => 'comment_confirm_delete_page',
'page arguments' => array(1),
'access arguments' => array('administer comments'),
'access callback' => 'entity_page_access',
'access arguments' => array(1, 'delete'),
'type' => MENU_LOCAL_TASK,
'file' => 'comment.admin.inc',
'weight' => 20,
......@@ -430,15 +433,14 @@ function comment_permission() {
* calculates the page number based on current comment settings and returns
* the full comment view with the pager set dynamically.
*
* @param $cid
* A comment identifier.
* @param \Drupal\comment\Plugin\Core\Entity\Comment $comment
* A comment entity.
*
* @return
* The comment listing set to the page on which the comment appears.
*/
function comment_permalink($cid) {
if (($comment = comment_load($cid)) && ($node = $comment->nid->entity)) {
function comment_permalink(Comment $comment) {
if ($node = $comment->nid->entity) {
// Find the current display page for this comment.
$page = comment_get_display_page($comment->id(), $node->type);
......@@ -928,46 +930,36 @@ function comment_view(Comment $comment, $view_mode = 'full', $langcode = NULL) {
function comment_links(Comment $comment, EntityInterface $node) {
$links = array();
if ($node->comment == COMMENT_NODE_OPEN) {
if (user_access('administer comments') && user_access('post comments')) {
if ($comment->access('delete')) {
$links['comment-delete'] = array(
'title' => t('delete'),
'href' => "comment/{$comment->id()}/delete",
'html' => TRUE,
);
$links['comment-edit'] = array(
'title' => t('edit'),
'href' => "comment/{$comment->id()}/edit",
'html' => TRUE,
);
$links['comment-reply'] = array(
'title' => t('reply'),
'href' => "comment/reply/{$comment->nid->target_id}/{$comment->id()}",
'html' => TRUE,
);
if ($comment->status->value == COMMENT_NOT_PUBLISHED) {
$links['comment-approve'] = array(
'title' => t('approve'),
'href' => "comment/{$comment->id()}/approve",
'html' => TRUE,
'query' => array('token' => drupal_get_token("comment/{$comment->id()}/approve")),
);
}
}
elseif (user_access('post comments')) {
if (comment_access('edit', $comment)) {
if ($comment->access('update')) {
$links['comment-edit'] = array(
'title' => t('edit'),
'href' => "comment/{$comment->id()}/edit",
'html' => TRUE,
);
}
}
if ($comment->access('create')) {
$links['comment-reply'] = array(
'title' => t('reply'),
'href' => "comment/reply/{$comment->nid->target_id}/{$comment->id()}",
'html' => TRUE,
);
}
else {
if ($comment->status->value == COMMENT_NOT_PUBLISHED && $comment->access('approve')) {
$links['comment-approve'] = array(
'title' => t('approve'),
'href' => "comment/{$comment->id()}/approve",
'html' => TRUE,
'query' => array('token' => drupal_get_token("comment/{$comment->id()}/approve")),
);
}
if (empty($links)) {
$links['comment-forbidden']['title'] = theme('comment_post_forbidden', array('node' => $node));
$links['comment-forbidden']['html'] = TRUE;
}
......@@ -1331,30 +1323,6 @@ function comment_user_predelete($account) {
comment_delete_multiple($cids);
}
/**
* Determines whether the current user has access to a particular comment.
*
* Authenticated users can edit their comments as long they have not been
* replied to. This prevents people from changing or revising their statements
* based on the replies to their posts.
*
* @param $op
* The operation that is to be performed on the comment. Only 'edit' is
* recognized now.
* @param Drupal\comment\Comment $comment
* The comment object.
*
* @return
* TRUE if the current user has acces to the comment, FALSE otherwise.
*/
function comment_access($op, Comment $comment) {
global $user;
if ($op == 'edit') {
return ($user->uid && $user->uid == $comment->uid->target_id && $comment->status->value == COMMENT_PUBLISHED && user_access('edit own comments')) || user_access('administer comments');
}
}
/**
* Accepts a submission of new or changed comment content.
*
......
......@@ -6,8 +6,8 @@
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\comment\Plugin\Core\Entity\Comment;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Form constructor for the comment reply form.
......@@ -102,26 +102,23 @@ function comment_reply(EntityInterface $node, $pid = NULL) {
/**
* Page callback: Publishes the specified comment.
*
* @param $cid
* A comment identifier.
* @param \Drupal\comment\Plugin\Core\Entity\Comment $comment
* A comment entity.
*
* @see comment_menu()
*/
function comment_approve($cid) {
function comment_approve(Comment $comment) {
// @todo CSRF tokens are validated in page callbacks rather than access
// callbacks, because access callbacks are also invoked during menu link
// generation. Add token support to routing: http://drupal.org/node/755584.
$token = drupal_container()->get('request')->query->get('token');
if (!isset($token) || !drupal_valid_token($token, "comment/$cid/approve")) {
if (!isset($token) || !drupal_valid_token($token, 'comment/' . $comment->id() . '/approve')) {
throw new AccessDeniedHttpException();
}
if ($comment = comment_load($cid)) {
$comment->status->value = COMMENT_PUBLISHED;
comment_save($comment);
$comment->status->value = COMMENT_PUBLISHED;
$comment->save();
drupal_set_message(t('Comment approved.'));
drupal_goto('node/' . $comment->nid->target_id);
}
throw new NotFoundHttpException();
drupal_set_message(t('Comment approved.'));
drupal_goto('node/' . $comment->nid->target_id);
}
<?php
/**
* @file
* Contains \Drupal\comment\CommentAccessController
*/
namespace Drupal\comment;
use Drupal\Core\Entity\EntityAccessController;
use Drupal\Core\Entity\EntityInterface;
use Drupal\user\Plugin\Core\Entity\User;
/**
* Access controller for the comment entity.
*
* @see \Drupal\comment\Plugin\Core\Entity\Comment.
*/
class CommentAccessController extends EntityAccessController implements CommentAccessControllerInterface {
/**
* Overrides \Drupal\Core\Entity\EntityAccessController::viewAccess().
*/
public function viewAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) {
return user_access('access comments', $account);
}
/**
* Overrides \Drupal\Core\Entity\EntityAccessController::createAccess().
*/
public function createAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) {
return user_access('post comments', $account);
}
/**
* Overrides \Drupal\Core\Entity\EntityAccessController::updateAccess().
*/
public function updateAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) {
// If no user is specified fill in the current one.
if (!isset($account)) {
$account = $GLOBALS['user'];
}
return ($account->uid && $account->uid == $entity->uid->value && $entity->status->value == COMMENT_PUBLISHED && user_access('edit own comments', $account)) || user_access('administer comments', $account);
}
/**
* Overrides \Drupal\Core\Entity\EntityAccessController::deleteAccess().
*/
public function deleteAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) {
return user_access('administer comments', $account);
}
/**
* Implements \Drupal\comment\CommentAccessControllerInterface::approveAccess().
*/
public function approveAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL) {
return user_access('administer comments', $account);
}
}
<?php
/**
* @file
* Contains \Drupal\comment\CommentAccessControllerInterface.
*/
namespace Drupal\comment;
use Drupal\Core\Entity\EntityAccessControllerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\user\Plugin\Core\Entity\User;
/**
* Defines an interface for comment access controller.
*
* Additional to EntityAccessControllerInterface this adds an access method for
* approving a comment.
*/
interface CommentAccessControllerInterface extends EntityAccessControllerInterface {
/**
* Checks 'approve' access for a given entity or entity translation.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity for which to check 'delete' access.
* @param string $langcode
* (optional) The language code for which to check access. Defaults to
* LANGUAGE_DEFAULT.
* @param \Drupal\user\Plugin\Core\Entity\User $account
* (optional) The user for which to check access, or NULL to check access
* for the current user. Defaults to NULL.
*
* @return bool
* TRUE if access was granted, FALSE otherwise.
*/
public function approveAccess(EntityInterface $entity, $langcode = LANGUAGE_DEFAULT, User $account = NULL);
}
......@@ -16,23 +16,6 @@
*/
class CommentTranslationController extends EntityTranslationControllerNG {
/**
* Overrides EntityTranslationController::getAccess().
*/
public function getAccess(EntityInterface $entity, $op) {
switch ($op) {
case 'view':
return user_access('access comments');
case 'update':
return comment_access('edit', $entity);
case 'delete':
return user_access('administer comments');
case 'create':
return user_access('post comments');
}
return parent::getAccess($entity, $op);
}
/**
* Overrides EntityTranslationController::entityFormTitle().
*/
......
......@@ -21,6 +21,7 @@
* bundle_label = @Translation("Content type"),
* module = "comment",
* controller_class = "Drupal\comment\CommentStorageController",
* access_controller_class = "Drupal\comment\CommentAccessController",
* render_controller_class = "Drupal\comment\CommentRenderController",
* form_controller_class = {
* "default" = "Drupal\comment\CommentFormController"
......
......@@ -41,7 +41,7 @@ function render_link($data, $values) {
parent::render_link($data, $values);
// ensure user has access to edit this comment.
$comment = $this->get_value($values);
if (!comment_access('edit', $comment)) {
if (!$comment->access('update')) {
return;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment