Merge pull request #163 from plone/moderation

notification moderator: link to commented page to moderate comments instead of links to approve or delete with CSRF confirmation
This commit is contained in:
Jens W. Klein 2019-12-03 13:51:35 +01:00 committed by GitHub
commit 7469a4f31c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 33 deletions

4
news/163.enhancement Normal file
View File

@ -0,0 +1,4 @@
Notification moderator: - Email commentator added
- Link to commented page for editing, approving, deleting comment instead of link to /@@moderate-publish-comment and @@moderate-delete-comment
/@@moderate-publish-comment : publish only pending comment, else show status message "comment already approved"
[ksuess]

View File

@ -13,6 +13,7 @@ from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.statusmessages.interfaces import IStatusMessage from Products.statusmessages.interfaces import IStatusMessage
from zope.event import notify from zope.event import notify
from zope.interface import alsoProvides
class View(BrowserView): class View(BrowserView):
@ -209,18 +210,25 @@ class PublishComment(BrowserView):
content_object = aq_parent(aq_parent(comment)) content_object = aq_parent(aq_parent(comment))
workflowTool = getToolByName(comment, 'portal_workflow', None) workflowTool = getToolByName(comment, 'portal_workflow', None)
workflow_action = self.request.form.get('workflow_action', 'publish') workflow_action = self.request.form.get('workflow_action', 'publish')
workflowTool.doActionFor(comment, workflow_action) review_state = workflowTool.getInfoFor(comment, 'review_state', '')
comment.reindexObject() if review_state == "pending":
content_object.reindexObject(idxs=['total_comments']) workflowTool.doActionFor(comment, workflow_action)
notify(CommentPublishedEvent(self.context, comment)) comment.reindexObject()
IStatusMessage(self.context.REQUEST).addStatusMessage( content_object.reindexObject(idxs=['total_comments'])
_('Comment approved.'), notify(CommentPublishedEvent(self.context, comment))
type='info') IStatusMessage(self.context.REQUEST).addStatusMessage(
_('Comment approved.'),
type='info')
else:
IStatusMessage(self.context.REQUEST).addStatusMessage(
_('Comment already approved.'),
type='info')
came_from = self.context.REQUEST.HTTP_REFERER came_from = self.context.REQUEST.HTTP_REFERER
# if the referrer already has a came_from in it, don't redirect back # if the referrer already has a came_from in it, don't redirect back
if (len(came_from) == 0 or 'came_from=' in came_from or if (len(came_from) == 0 or 'came_from=' in came_from or
not getToolByName( not getToolByName(
content_object, 'portal_url').isURLInPortal(came_from)): content_object, 'portal_url').isURLInPortal(came_from) or
'@@confirm-action' in came_from):
came_from = content_object.absolute_url() came_from = content_object.absolute_url()
return self.context.REQUEST.RESPONSE.redirect(came_from) return self.context.REQUEST.RESPONSE.redirect(came_from)

View File

@ -58,12 +58,12 @@ MAIL_NOTIFICATION_MESSAGE = _(
MAIL_NOTIFICATION_MESSAGE_MODERATOR = _( MAIL_NOTIFICATION_MESSAGE_MODERATOR = _(
u'mail_notification_message_moderator', u'mail_notification_message_moderator',
default=u'A comment on "${title}" ' default=u'A comment on "${title}" '
u'has been posted here: ${link}\n\n' u'has been posted by ${commentator}\n'
u'---\n' u'here: ${link}\n\n'
u'${text}\n'
u'---\n\n' u'---\n\n'
u'Approve comment:\n${link_approve}\n\n' u'${text}\n\n'
u'Delete comment:\n${link_delete}\n', u'---\n\n'
u'Log in to moderate.\n\n',
) )
logger = logging.getLogger('plone.app.discussion') logger = logging.getLogger('plone.app.discussion')
@ -419,8 +419,6 @@ def notify_moderator(obj, event):
# Compose email # Compose email
subject = translate(_(u'A comment has been posted.'), context=obj.REQUEST) subject = translate(_(u'A comment has been posted.'), context=obj.REQUEST)
link_approve = obj.absolute_url() + '/@@moderate-publish-comment'
link_delete = obj.absolute_url() + '/@@moderate-delete-comment'
message = translate( message = translate(
Message( Message(
MAIL_NOTIFICATION_MESSAGE_MODERATOR, MAIL_NOTIFICATION_MESSAGE_MODERATOR,
@ -428,8 +426,14 @@ def notify_moderator(obj, event):
'title': safe_unicode(content_object.title), 'title': safe_unicode(content_object.title),
'link': content_object.absolute_url() + '/view#' + obj.id, 'link': content_object.absolute_url() + '/view#' + obj.id,
'text': obj.text, 'text': obj.text,
'link_approve': link_approve, 'commentator': obj.author_email or translate(
'link_delete': link_delete, Message(
_(
u'label_anonymous',
default=u'Anonymous',
),
),
)
}, },
), ),
context=obj.REQUEST, context=obj.REQUEST,

View File

@ -197,9 +197,10 @@ class TestModeratorNotificationUnit(unittest.TestCase):
provided=IMailHost) provided=IMailHost)
def test_notify_moderator(self): def test_notify_moderator(self):
# Add a comment and make sure an email is send to the moderator. """Add a comment and make sure an email is send to the moderator."""
comment = createObject('plone.Comment') comment = createObject('plone.Comment')
comment.text = 'Comment text' comment.text = 'Comment text'
comment.author_email = 'john@plone.test'
comment_id = self.conversation.addComment(comment) comment_id = self.conversation.addComment(comment)
@ -215,27 +216,20 @@ class TestModeratorNotificationUnit(unittest.TestCase):
# The output should be encoded in a reasonable manner # The output should be encoded in a reasonable manner
# (in this case quoted-printable): # (in this case quoted-printable):
self.assertTrue( self.assertTrue(
'A comment on "K=C3=B6lle Alaaf" has been posted here:' 'A comment on "K=C3=B6lle Alaaf" has been posted'
in msg) in msg
self.assertIn(
'http://nohost/plone/d=\noc1/view#{0}'.format(comment_id),
msg,
) )
self.assertIn( self.assertIn(
'Comment text', 'http://nohost/plone/doc1/view#{0}'.format(comment_id),
msg, msg
) )
text = 'Approve comment:\nhttp://nohost/plone/doc1/' \
'++conversation++default/{0}/@@moderat=\ne-publish-comment'
self.assertIn( self.assertIn(
text.format(comment_id), comment.author_email,
msg, msg
) )
text = 'Delete comment:\nhttp://nohost/plone/doc1/' \
'++conversation++default/{0}/@@moderat=\ne-delete-comment'
self.assertIn( self.assertIn(
text.format(comment_id), comment.text,
msg, msg
) )
def test_notify_moderator_specific_address(self): def test_notify_moderator_specific_address(self):