Skip to content

Commit

Permalink
ENHANCEMENT Added PageComment->canView()/canEdit()/canDelete(), and u…
Browse files Browse the repository at this point in the history
…sing these permissions in PageCommentInterface. Caution: canCreate() actions are still determined by PageCommentInterface::$comments_require_login/$comments_require_permission

BUGFIX Requiring CMS_ACCESS_CommentAdmin instead of ADMIN permissions in PageCommentInterface and CommentAdmin administrative actions

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@104968 467b73ca-7a2a-4603-9d3b-597d59a354a9
  • Loading branch information
chillu authored and Sam Minnee committed Feb 2, 2011
1 parent 24b83db commit 97c1ff1
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 81 deletions.
202 changes: 131 additions & 71 deletions code/sitefeatures/PageComment.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function ParsedBBCode(){
}

function DeleteLink() {
return (Permission::check('CMS_ACCESS_CMSMain')) ? "PageComment_Controller/deletecomment/$this->ID" : false;
return ($this->canDelete()) ? "PageComment_Controller/deletecomment/$this->ID" : false;
}

function CommentTextWithLinks() {
Expand All @@ -70,15 +70,15 @@ function CommentTextWithLinks() {
}

function SpamLink() {
return (Permission::check('CMS_ACCESS_CMSMain') && !$this->IsSpam) ? "PageComment_Controller/reportspam/$this->ID" : false;
return ($this->canEdit() && !$this->IsSpam) ? "PageComment_Controller/reportspam/$this->ID" : false;
}

function HamLink() {
return (Permission::check('CMS_ACCESS_CMSMain') && $this->IsSpam) ? "PageComment_Controller/reportham/$this->ID" : false;
return ($this->canEdit() && $this->IsSpam) ? "PageComment_Controller/reportham/$this->ID" : false;
}

function ApproveLink() {
return (Permission::check('CMS_ACCESS_CMSMain') && $this->NeedsModeration) ? "PageComment_Controller/approve/$this->ID" : false;
return ($this->canEdit() && $this->NeedsModeration) ? "PageComment_Controller/approve/$this->ID" : false;
}

function SpamClass() {
Expand Down Expand Up @@ -156,6 +156,77 @@ public function onBeforeWrite() {
}
}
}

/**
* This always returns true, and should be handled by {@link PageCommentInterface->CanPostComment()}.
*
* @todo Integrate with PageCommentInterface::$comments_require_permission and $comments_require_login
*
* @param Member $member
* @return Boolean
*/
function canCreate($member = null) {
return true;
}

/**
* Checks for association with a page,
* and {@link SiteTree->ProvidePermission} flag being set to TRUE.
* Note: There's an additional layer of permission control
* in {@link PageCommentInterface}.
*
* @param Member $member
* @return Boolean
*/
function canView($member = null) {
if(!$member) $member = Member::currentUser();

// Standard mechanism for accepting permission changes from decorators
$extended = $this->extendedCan('canView', $member);
if($extended !== null) return $extended;

$page = $this->Parent();
return (
($page && $page->ProvideComments)
|| (bool)Permission::checkMember($member, 'CMS_ACCESS_CommentAdmin')
);
}

/**
* Checks for "CMS_ACCESS_CommentAdmin" permission codes
* and {@link canView()}.
*
* @param Member $member
* @return Boolean
*/
function canEdit($member = null) {
if(!$member) $member = Member::currentUser();

// Standard mechanism for accepting permission changes from decorators
$extended = $this->extendedCan('canEdit', $member);
if($extended !== null) return $extended;

if(!$this->canView($member)) return false;

return (bool)Permission::checkMember($member, 'CMS_ACCESS_CommentAdmin');
}

/**
* Checks for "CMS_ACCESS_CommentAdmin" permission codes
* and {@link canEdit()}.
*
* @param Member $member
* @return Boolean
*/
function canDelete($member = null) {
if(!$member) $member = Member::currentUser();

// Standard mechanism for accepting permission changes from decorators
$extended = $this->extendedCan('canDelete', $member);
if($extended !== null) return $extended;

return $this->canEdit($member);
}
}


Expand All @@ -180,13 +251,11 @@ function rss() {
* Deletes all comments on the page referenced by the url param pageid
*/
function deleteallcomments() {
if(Permission::check('CMS_ACCESS_CMSMain')) {
$pageId = $_REQUEST['pageid'];
if(preg_match('/^\d+$/', $pageId)) {
$comments = DataObject::get("PageComment", "\"ParentID\" = $pageId");
if($comments) foreach($comments as $c) {
$c->delete();
}
$pageId = $_REQUEST['pageid'];
if(preg_match('/^\d+$/', $pageId)) {
$comments = DataObject::get("PageComment", "\"ParentID\" = $pageId");
if($comments) foreach($comments as $c) {
if($c->canDelete()) $c->delete();
}
}

Expand All @@ -198,11 +267,9 @@ function deleteallcomments() {
}

function deletecomment() {
if(Permission::check('CMS_ACCESS_CMSMain')) {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
if($comment) {
$comment->delete();
}
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
if($comment && $comment->canDelete()) {
$comment->delete();
}

if(Director::is_ajax()) {
Expand All @@ -213,52 +280,47 @@ function deletecomment() {
}

function approve() {
if(Permission::check('CMS_ACCESS_CMSMain')) {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);

if($comment) {
$comment->NeedsModeration = false;
$comment->write();

// @todo Report to spamprotecter this is true

if(Director::is_ajax()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
Director::redirectBack();
}
if($comment && $comment->canEdit()) {
$comment->NeedsModeration = false;
$comment->write();

// @todo Report to spamprotecter this is true

if(Director::is_ajax()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
Director::redirectBack();
}
}
}

function reportspam() {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
if($comment) {
// check they have access
if(Permission::check('CMS_ACCESS_CMSMain')) {

// if spam protection module exists
if(class_exists('SpamProtectorManager')) {
SpamProtectorManager::send_feedback($comment, 'spam');
}

// If Akismet is enabled
else if(SSAkismet::isEnabled()) {
try {
$akismet = new SSAkismet();
$akismet->setCommentAuthor($comment->getField('Name'));
$akismet->setCommentContent($comment->getField('Comment'));
$akismet->submitSpam();
} catch (Exception $e) {
// Akismet didn't work, most likely the service is down.
}
if($comment && $comment->canEdit()) {
// if spam protection module exists
if(class_exists('SpamProtectorManager')) {
SpamProtectorManager::send_feedback($comment, 'spam');
}

// If Akismet is enabled
else if(SSAkismet::isEnabled()) {
try {
$akismet = new SSAkismet();
$akismet->setCommentAuthor($comment->getField('Name'));
$akismet->setCommentContent($comment->getField('Comment'));
$akismet->submitSpam();
} catch (Exception $e) {
// Akismet didn't work, most likely the service is down.
}

$comment->IsSpam = true;
$comment->NeedsModeration = false;
$comment->write();
}

$comment->IsSpam = true;
$comment->NeedsModeration = false;
$comment->write();
}

if(Director::is_ajax()) {
if(SSAkismet::isEnabled() && SSAkismet::getSaveSpam()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
Expand All @@ -274,28 +336,26 @@ function reportspam() {
*/
function reportham() {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
if($comment) {
if(Permission::check('CMS_ACCESS_CMSMain')) {

// if spam protection module exists
if(class_exists('SpamProtectorManager')) {
SpamProtectorManager::send_feedback($comment, 'ham');
}

if(SSAkismet::isEnabled()) {
try {
$akismet = new SSAkismet();
$akismet->setCommentAuthor($comment->getField('Name'));
$akismet->setCommentContent($comment->getField('Comment'));
$akismet->submitHam();
} catch (Exception $e) {
// Akismet didn't work, most likely the service is down.
}
if($comment && $comment->canEdit()) {
// if spam protection module exists
if(class_exists('SpamProtectorManager')) {
SpamProtectorManager::send_feedback($comment, 'ham');
}

if(SSAkismet::isEnabled()) {
try {
$akismet = new SSAkismet();
$akismet->setCommentAuthor($comment->getField('Name'));
$akismet->setCommentContent($comment->getField('Comment'));
$akismet->submitHam();
} catch (Exception $e) {
// Akismet didn't work, most likely the service is down.
}
$comment->setField('IsSpam', false);
$comment->write();
}
$comment->setField('IsSpam', false);
$comment->write();
}

if(Director::is_ajax()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
Expand Down
4 changes: 2 additions & 2 deletions code/sitefeatures/PageCommentInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ function Comments() {
$limit['limit'] = PageComment::$comments_per_page;

$spamfilter = isset($_GET['showspam']) ? '' : "AND \"IsSpam\" = 0";
$unmoderatedfilter = Permission::check('ADMIN') ? '' : "AND \"NeedsModeration\" = 0";
$unmoderatedfilter = Permission::check('CMS_ACCESS_CommentAdmin') ? '' : "AND \"NeedsModeration\" = 0";
$order = self::$order_comments_by;
$comments = DataObject::get("PageComment", "\"ParentID\" = '" . Convert::raw2sql($this->page->ID) . "' $spamfilter $unmoderatedfilter", $order, "", $limit);

Expand All @@ -254,7 +254,7 @@ function CommentRssLink() {
* comments on a page referenced by the url param pageid
*/
function DeleteAllLink() {
if(Permission::check('CMS_ACCESS_CMSMain')) {
if(Permission::check('CMS_ACCESS_CommentAdmin')) {
return Director::absoluteBaseURL() . "PageComment/deleteallcomments?pageid=" . $this->page->ID;
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/CommentAdminTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function testNumSpam(){
function testdeletemarked(){
$comm = $this->objFromFixture('PageComment', 'Comment1');
$id = $comm->ID;
$this->logInWithPermission('ADMIN');
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$result = $this->get("admin/comments/EditForm/field/Comments/item/$id/delete");
$checkComm = DataObject::get_by_id('PageComment',$id);

Expand Down
55 changes: 53 additions & 2 deletions tests/PageCommentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,64 @@ class PageCommentsTest extends FunctionalTest {

static $fixture_file = 'cms/tests/PageCommentsTest.yml';

function testCanView() {
$visitor = $this->objFromFixture('Member', 'visitor');
$admin = $this->objFromFixture('Member', 'commentadmin');
$comment = $this->objFromFixture('PageComment', 'firstComA');

$this->assertTrue($comment->canView($visitor),
'Unauthenticated members can view comments associated to a page with ProvideComments=1'
);
$this->assertTrue($comment->canView($admin),
'Admins with CMS_ACCESS_CommentAdmin permissions can view comments associated to a page with ProvideComments=1'
);

$disabledComment = $this->objFromFixture('PageComment', 'disabledCom');

$this->assertFalse($disabledComment->canView($visitor),
'Unauthenticated members can not view comments associated to a page with ProvideComments=0'
);
$this->assertTrue($disabledComment->canView($admin),
'Admins with CMS_ACCESS_CommentAdmin permissions can view comments associated to a page with ProvideComments=0'
);
}

function testDeleteAllCommentsOnPage() {
function testCanEdit() {
$visitor = $this->objFromFixture('Member', 'visitor');
$admin = $this->objFromFixture('Member', 'commentadmin');
$comment = $this->objFromFixture('PageComment', 'firstComA');

$this->assertFalse($comment->canEdit($visitor));
$this->assertTrue($comment->canEdit($admin));
}

function testCanDelete() {
$visitor = $this->objFromFixture('Member', 'visitor');
$admin = $this->objFromFixture('Member', 'commentadmin');
$comment = $this->objFromFixture('PageComment', 'firstComA');

$this->assertFalse($comment->canEdit($visitor));
$this->assertTrue($comment->canEdit($admin));
}

function testDeleteComment() {
$firstPage = $this->objFromFixture('Page', 'first');
$this->autoFollowRedirection = false;
$this->logInAs('commentadmin');

$firstComment = $this->objFromFixture('PageComment', 'firstComA');
$firstCommentID = $firstComment->ID;
Director::test($firstPage->RelativeLink(), null, $this->session());
Director::test('PageComment/deletecomment/'.$firstComment->ID, null, $this->session());

$this->assertFalse(DataObject::get_by_id('PageComment', $firstCommentID));
}

function testDeleteAllCommentsOnPage() {
$second = $this->objFromFixture('Page', 'second');
$this->autoFollowRedirection = false;
$this->logInAs('admin');
$this->logInAs('commentadmin');

Director::test('second-page', null, $this->session());
Director::test('PageComment/deleteallcomments?pageid='.$second->ID,
null, $this->session());
Expand Down
Loading

0 comments on commit 97c1ff1

Please sign in to comment.