Add links to delete/approve a comment in the moderator notification email.

Remove the unnecessary workflow_action parameter from the PublishComments request.

svn path=/plone.app.discussion/trunk/; revision=49045
This commit is contained in:
Timo Stollenwerk 2011-04-22 17:09:09 +00:00
parent 521ea78ce3
commit e75685d5c0
5 changed files with 144 additions and 126 deletions

View File

@ -4,6 +4,13 @@ Changelog
2.0.1 (2011-04-22)
------------------
- Add links to delete/approve a comment in the moderator notification email.
[timo]
- Remove the unnecessary workflow_action parameter from the PublishComments
request.
[timo]
- Make sure the email settings in the control panel are disabled when commenting
is disabled globally.
[timo]

View File

@ -57,7 +57,6 @@
$.ajax({
type: "GET",
url: target,
data: "workflow_action=publish",
success: function (msg) {
// fade out row
$(row).fadeOut("normal", function () {

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from Acquisition import aq_inner, aq_parent
from Products.Five.browser import BrowserView
@ -12,9 +13,8 @@ from plone.app.discussion.interfaces import IComment
class View(BrowserView):
"""Main moderation View.
"""Comment moderation view.
"""
template = ViewPageTemplateFile('moderation.pt')
try:
template.id = '@@moderate-comments'
@ -23,13 +23,9 @@ class View(BrowserView):
pass
def __call__(self):
# Hide the editable-object border
self.request.set('disable_border', True)
context = aq_inner(self.context)
catalog = getToolByName(context, 'portal_catalog')
self.comments = catalog(object_provides=IComment.__identifier__,
review_state='pending',
sort_on='created',
@ -42,9 +38,9 @@ class View(BrowserView):
a 'pending' workflow state.
"""
context = aq_inner(self.context)
wf_tool = getToolByName(context, 'portal_workflow')
comment_workflow = wf_tool.getChainForPortalType('Discussion Item')[0]
comment_workflow = wf_tool[comment_workflow]
workflowTool = getToolByName(context, 'portal_workflow')
comment_workflow = workflowTool.getChainForPortalType('Discussion Item')[0]
comment_workflow = workflowTool[comment_workflow]
if 'pending' in comment_workflow.states:
return True
else:
@ -59,9 +55,9 @@ class ModerateCommentsEnabled(BrowserView):
a 'pending' workflow state.
"""
context = aq_inner(self.context)
wf_tool = getToolByName(context, 'portal_workflow', None)
comment_workflow = wf_tool.getChainForPortalType('Discussion Item')[0]
comment_workflow = wf_tool[comment_workflow]
workflowTool = getToolByName(context, 'portal_workflow', None)
comment_workflow = workflowTool.getChainForPortalType('Discussion Item')[0]
comment_workflow = workflowTool[comment_workflow]
if 'pending' in comment_workflow.states:
return True
else:
@ -90,20 +86,17 @@ class DeleteComment(BrowserView):
"""
def __call__(self):
context = aq_inner(self.context)
comment_id = self.context.id
conversation = aq_parent(context)
del conversation[comment_id]
comment = aq_inner(self.context)
conversation = aq_parent(comment)
content_object = aq_parent(conversation)
del conversation[comment.id]
IStatusMessage(self.context.REQUEST).addStatusMessage(
_("Comment deleted."),
type="info")
return self.context.REQUEST.RESPONSE.redirect(
self.context.REQUEST.HTTP_REFERER)
came_from = self.context.REQUEST.HTTP_REFERER
if len(came_from) == 0:
came_from = content_object.absolute_url()
return self.context.REQUEST.RESPONSE.redirect(came_from)
class PublishComment(BrowserView):
@ -128,22 +121,21 @@ class PublishComment(BrowserView):
"""
def __call__(self):
comment = aq_inner(self.context)
workflow_action = self.request.form['workflow_action']
portal_workflow = getToolByName(comment, 'portal_workflow')
portal_workflow.doActionFor(comment, workflow_action)
catalog = getToolByName(comment, 'portal_catalog')
catalog.reindexObject(comment)
content_object = aq_parent(aq_parent(comment))
workflowTool = getToolByName(comment, 'portal_workflow', None)
current_state = workflowTool.getInfoFor(comment, 'review_state')
if current_state != 'published':
workflowTool.doActionFor(comment, 'publish')
catalogTool = getToolByName(comment, 'portal_catalog')
catalogTool.reindexObject(comment)
IStatusMessage(self.context.REQUEST).addStatusMessage(
_("Comment approved."),
type="info")
return self.context.REQUEST.RESPONSE.redirect(
self.context.REQUEST.HTTP_REFERER)
came_from = self.context.REQUEST.HTTP_REFERER
if len(came_from) == 0:
came_from = content_object.absolute_url()
return self.context.REQUEST.RESPONSE.redirect(came_from)
class BulkActionsView(BrowserView):
"""Bulk actions (unapprove, approve, delete, mark as spam).
@ -169,11 +161,8 @@ class BulkActionsView(BrowserView):
"""
def __call__(self):
if 'form.select.BulkAction' in self.request:
bulkaction = self.request.get('form.select.BulkAction')
self.paths = self.request.get('paths')
if self.paths:
if bulkaction == '-1':
@ -204,10 +193,10 @@ class BulkActionsView(BrowserView):
context = aq_inner(self.context)
for path in self.paths:
comment = context.restrictedTraverse(path)
portal_workflow = getToolByName(comment, 'portal_workflow')
current_state = portal_workflow.getInfoFor(comment, 'review_state')
workflowTool = getToolByName(comment, 'portal_workflow')
current_state = workflowTool.getInfoFor(comment, 'review_state')
if current_state != 'published':
portal_workflow.doActionFor(comment, 'publish')
workflowTool.doActionFor(comment, 'publish')
catalog = getToolByName(comment, 'portal_catalog')
catalog.reindexObject(comment)

View File

@ -43,16 +43,28 @@ from Products.CMFCore.CMFCatalogAware import WorkflowAware
from OFS.role import RoleManager
COMMENT_TITLE = _(u"comment_title",
COMMENT_TITLE = _(
u"comment_title",
default=u"${creator} on ${content}")
MAIL_NOTIFICATION_MESSAGE = _(u"mail_notification_message",
MAIL_NOTIFICATION_MESSAGE = _(
u"mail_notification_message",
default=u"A comment on '${title}' "
"has been posted here: ${link}\n\n"
"---\n\n"
"${text}"
"---\n"
"${text}\n"
"---\n")
MAIL_NOTIFICATION_MESSAGE_MODERATOR = _(
u"mail_notification_message_moderator",
default=u"A comment on '${title}' "
"has been posted here: ${link}\n\n"
"---\n"
"${text}\n"
"---\n\n"
"Approve comment:\n${link_approve}\n\n"
"Delete comment:\n${link_delete}\n")
logger = logging.getLogger("plone.app.discussion")
@ -179,6 +191,7 @@ class Comment(CatalogAware, WorkflowAware, DynamicType, Traversable,
CommentFactory = Factory(Comment)
def notify_workflow(obj, event):
"""Tell the workflow tool when a comment is added
"""
@ -186,6 +199,7 @@ def notify_workflow(obj, event):
if tool is not None:
tool.notifyCreated(obj)
def notify_content_object(obj, event):
"""Tell the content object when a comment is added
"""
@ -274,16 +288,15 @@ def notify_user(obj, event):
def notify_moderator(obj, event):
"""Tell the moderator when a comment needs attention.
This method sends an email to the moderator if comment moderation is
enabled and a new comment has been added that needs to be approved.
This method sends an email to the moderator if comment moderation a new
comment has been added that needs to be approved.
The moderator_notification setting has to be enabled in the discussion
control panel.
Configure the moderator e-mail address in the discussion control panel.
If no moderator is configured but moderator notifications are turned on,
the site admin email (from the mail control panel) will be used.
This requires the moderator_notification to be enabled in the discussion
control panel and the comment_review_workflow enabled for the comment
content type.
"""
# Check if moderator notification is enabled
registry = queryUtility(IRegistry)
@ -310,13 +323,15 @@ def notify_moderator(obj, event):
content_object = aq_parent(conversation)
# Compose email
#comment = conversation.getComments().next()
subject = translate(_(u"A comment has been posted."), context=obj.REQUEST)
message = translate(Message(MAIL_NOTIFICATION_MESSAGE,
mapping={'title': safe_unicode(content_object.title),
'link': content_object.absolute_url() +
'/view#' + obj.id,
'text': obj.text}),
message = translate(Message(MAIL_NOTIFICATION_MESSAGE_MODERATOR,
mapping={
'title': safe_unicode(content_object.title),
'link': content_object.absolute_url() + '/view#' + obj.id,
'text': obj.text,
'link_approve': obj.absolute_url() + '/@@moderate-publish-comment',
'link_delete': obj.absolute_url() + '/@@moderate-delete-comment',
}),
context=obj.REQUEST)
# Send email

View File

@ -88,6 +88,8 @@ class TestUserNotificationUnit(unittest.TestCase):
% comment_id
in msg)
self.assertTrue('Comment text' in msg)
self.assertFalse('Approve comment' in msg)
self.assertFalse('Delete comment' in msg)
def test_do_not_notify_user_when_notification_is_disabled(self):
registry = queryUtility(IRegistry)
@ -222,6 +224,12 @@ class TestModeratorNotificationUnit(unittest.TestCase):
% comment_id
in msg)
self.assertTrue('Comment text' in msg)
self.assertTrue(
'Approve comment:\nhttp://nohost/plone/doc1/++conversation++default/%s/@@moderat=\ne-publish-comment'
% comment_id in msg)
self.assertTrue(
'Delete comment:\nhttp://nohost/plone/doc1/++conversation++default/%s/@@moderat=\ne-delete-comment'
% comment_id in msg)
def test_notify_moderator_specific_address(self):
# A moderator email address can be specified in the control panel.