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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user