Delete own comments
Add permission to allow comment authors to delete their own comments if there are no replies yet.
This commit is contained in:
parent
3eab51e1c4
commit
a7b3c818f2
@ -3,9 +3,17 @@ Changelog
|
||||
|
||||
2.1.6 (unreleased)
|
||||
------------------
|
||||
- Add permission to allow comment authors to delete their own comments if
|
||||
there are no replies yet.
|
||||
[gaudenz]
|
||||
|
||||
- Add Site Administrator role to Review comments permission.
|
||||
[gaudenz]
|
||||
|
||||
- Add permission to allow comment authors to delete their own comments if
|
||||
there are no replies yet.
|
||||
[gaudenz]
|
||||
|
||||
- Fix excessive JS comment deletion.
|
||||
[gaudenz]
|
||||
|
||||
|
@ -83,6 +83,19 @@
|
||||
<span tal:replace="structure reply/getText" />
|
||||
|
||||
<div class="commentActions">
|
||||
<form name="delete"
|
||||
action=""
|
||||
method="post"
|
||||
tal:condition="python: not view.can_review() and view.could_delete_own(reply)"
|
||||
tal:attributes="action string:${reply/absolute_url}/@@delete-own-comment;
|
||||
style python:view.can_delete_own(reply) and 'display: inline' or 'display: none'">
|
||||
<input name="form.button.DeleteComment"
|
||||
class="destructive"
|
||||
type="submit"
|
||||
value="Delete"
|
||||
i18n:attributes="value label_delete;"
|
||||
/>
|
||||
</form>
|
||||
<form name="delete"
|
||||
action=""
|
||||
method="post"
|
||||
|
@ -190,6 +190,7 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
# Member
|
||||
member = portal_membership.getAuthenticatedMember()
|
||||
username = member.getUserName()
|
||||
userid = member.getUserId()
|
||||
email = member.getProperty('email')
|
||||
fullname = member.getProperty('fullname')
|
||||
if not fullname or fullname == '':
|
||||
@ -206,6 +207,10 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
comment.user_notification = user_notification
|
||||
comment.creation_date = datetime.utcnow()
|
||||
comment.modification_date = datetime.utcnow()
|
||||
|
||||
# add local "Owner" role for current user
|
||||
comment.manage_setLocalRoles(userid, ['Owner'])
|
||||
|
||||
else: # pragma: no cover
|
||||
raise Unauthorized("Anonymous user tries to post a comment, but "
|
||||
"anonymous commenting is disabled. Or user does not have the "
|
||||
@ -283,6 +288,24 @@ class CommentsViewlet(ViewletBase):
|
||||
return getSecurityManager().checkPermission('Review comments',
|
||||
aq_inner(self.context))
|
||||
|
||||
def can_delete_own(self, comment):
|
||||
"""Returns true if the current user can delete the comment. Only
|
||||
comments without replies can be deleted.
|
||||
"""
|
||||
try:
|
||||
return comment.restrictedTraverse('@@delete-own-comment').can_delete()
|
||||
except Unauthorized:
|
||||
return False
|
||||
|
||||
def could_delete_own(self, comment):
|
||||
"""Returns true if the current user could delete the comment if it had no
|
||||
replies. This is used to prepare hidden form buttons for JS.
|
||||
"""
|
||||
try:
|
||||
return comment.restrictedTraverse('@@delete-own-comment').could_delete()
|
||||
except Unauthorized:
|
||||
return False
|
||||
|
||||
def is_discussion_allowed(self):
|
||||
context = aq_inner(self.context)
|
||||
return context.restrictedTraverse('@@conversation_view').enabled()
|
||||
@ -346,7 +369,6 @@ class CommentsViewlet(ViewletBase):
|
||||
conversation = IConversation(context)
|
||||
|
||||
wf = getToolByName(context, 'portal_workflow')
|
||||
|
||||
# workflow_actions is only true when user
|
||||
# has 'Manage portal' permission
|
||||
|
||||
|
@ -71,7 +71,7 @@
|
||||
permission="zope2.View"
|
||||
/>
|
||||
|
||||
<!-- Delete comment view -->
|
||||
<!-- Delete comment views -->
|
||||
<browser:page
|
||||
for="plone.app.discussion.interfaces.IComment"
|
||||
name="moderate-delete-comment"
|
||||
@ -80,6 +80,14 @@
|
||||
permission="plone.app.discussion.ReviewComments"
|
||||
/>
|
||||
|
||||
<browser:page
|
||||
for="plone.app.discussion.interfaces.IComment"
|
||||
name="delete-own-comment"
|
||||
layer="..interfaces.IDiscussionLayer"
|
||||
class=".moderation.DeleteOwnComment"
|
||||
permission="plone.app.discussion.DeleteOwnComments"
|
||||
/>
|
||||
|
||||
<!-- Publish comment view -->
|
||||
<browser:page
|
||||
for="plone.app.discussion.interfaces.IComment"
|
||||
|
@ -193,6 +193,9 @@
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
// Add delete button to the parent
|
||||
var parent = comment.prev('[class*="replyTreeLevel' + (treelevel - 1) + '"]');
|
||||
parent.find('form[name="delete"]').css('display', 'inline');
|
||||
// remove comment
|
||||
$(this).fadeOut('fast', function () {
|
||||
$(this).remove();
|
||||
|
@ -1,6 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from Acquisition import aq_inner, aq_parent
|
||||
|
||||
from AccessControl import Unauthorized, getSecurityManager
|
||||
|
||||
from Products.Five.browser import BrowserView
|
||||
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
||||
|
||||
@ -10,6 +12,7 @@ from Products.statusmessages.interfaces import IStatusMessage
|
||||
|
||||
from plone.app.discussion.interfaces import _
|
||||
from plone.app.discussion.interfaces import IComment
|
||||
from plone.app.discussion.interfaces import IReplies
|
||||
|
||||
|
||||
class View(BrowserView):
|
||||
@ -104,6 +107,34 @@ class DeleteComment(BrowserView):
|
||||
return self.context.REQUEST.RESPONSE.redirect(came_from)
|
||||
|
||||
|
||||
class DeleteOwnComment(DeleteComment):
|
||||
"""Delete an own comment if it has no replies. Following conditions have to be true
|
||||
for a user to be able to delete his comments:
|
||||
* "Delete own comments" permission
|
||||
* no replies to the comment
|
||||
* Owner role directly assigned on the comment object
|
||||
"""
|
||||
|
||||
def could_delete(self):
|
||||
"""returns true if the comment could be deleted if it had no replies."""
|
||||
sm = getSecurityManager()
|
||||
context = aq_inner(self.context)
|
||||
userid = sm.getUser().getId()
|
||||
return (sm.checkPermission('Delete own comments',
|
||||
context)
|
||||
and 'Owner' in context.get_local_roles_for_userid(userid))
|
||||
|
||||
def can_delete(self):
|
||||
return (len(IReplies(aq_inner(self.context))) == 0
|
||||
and self.could_delete())
|
||||
|
||||
def __call__(self):
|
||||
if self.can_delete():
|
||||
super(DeleteOwnComment, self).__call__()
|
||||
else:
|
||||
raise Unauthorized("Your not allowed to delete this comment.")
|
||||
|
||||
|
||||
class PublishComment(BrowserView):
|
||||
"""Publish a comment.
|
||||
|
||||
|
@ -9,4 +9,9 @@
|
||||
title="Review comments"
|
||||
/>
|
||||
|
||||
<permission
|
||||
id="plone.app.discussion.DeleteOwnComments"
|
||||
title="Delete own comments"
|
||||
/>
|
||||
|
||||
</configure>
|
||||
|
@ -9,5 +9,11 @@
|
||||
<permission name="Reply to item" acquire="False">
|
||||
<role name="Authenticated"/>
|
||||
</permission>
|
||||
<permission name="Delete own comments" acquire="False">
|
||||
<role name="Manager"/>
|
||||
<role name="Site Administrator"/>
|
||||
<role name="Reviewer"/>
|
||||
<role name="Owner"/>
|
||||
</permission>
|
||||
</permissions>
|
||||
</rolemap>
|
||||
|
Loading…
Reference in New Issue
Block a user