commit
115e984339
@ -22,6 +22,8 @@ Bug fixes:
|
|||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
|
|
||||||
|
- Cleaned code from flake8 errors. [maurits]
|
||||||
|
|
||||||
- Reset the required setting of the author_email widget each time.
|
- Reset the required setting of the author_email widget each time.
|
||||||
Otherwise, the email field might get set to required when an
|
Otherwise, the email field might get set to required when an
|
||||||
anonymous user visits, and then remain required when an
|
anonymous user visits, and then remain required when an
|
||||||
|
@ -143,6 +143,94 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
|||||||
self.actions['cancel'].addClass('hide')
|
self.actions['cancel'].addClass('hide')
|
||||||
self.actions['comment'].addClass('context')
|
self.actions['comment'].addClass('context')
|
||||||
|
|
||||||
|
def get_author(self, data):
|
||||||
|
context = aq_inner(self.context)
|
||||||
|
# some attributes are not always set
|
||||||
|
author_name = u''
|
||||||
|
|
||||||
|
# Make sure author_name/ author_email is properly encoded
|
||||||
|
if 'author_name' in data:
|
||||||
|
author_name = data['author_name']
|
||||||
|
if isinstance(author_name, str):
|
||||||
|
author_name = unicode(author_name, 'utf-8')
|
||||||
|
if 'author_email' in data:
|
||||||
|
author_email = data['author_email']
|
||||||
|
if isinstance(author_email, str):
|
||||||
|
author_email = unicode(author_email, 'utf-8')
|
||||||
|
|
||||||
|
# Set comment author properties for anonymous users or members
|
||||||
|
portal_membership = getToolByName(context, 'portal_membership')
|
||||||
|
anon = portal_membership.isAnonymousUser()
|
||||||
|
if not anon and getSecurityManager().checkPermission(
|
||||||
|
'Reply to item', context):
|
||||||
|
# Member
|
||||||
|
member = portal_membership.getAuthenticatedMember()
|
||||||
|
# memberdata is stored as utf-8 encoded strings
|
||||||
|
email = member.getProperty('email')
|
||||||
|
fullname = member.getProperty('fullname')
|
||||||
|
if not fullname or fullname == '':
|
||||||
|
fullname = member.getUserName()
|
||||||
|
elif isinstance(fullname, str):
|
||||||
|
fullname = unicode(fullname, 'utf-8')
|
||||||
|
author_name = fullname
|
||||||
|
if email and isinstance(email, str):
|
||||||
|
email = unicode(email, 'utf-8')
|
||||||
|
# XXX: according to IComment interface author_email must not be
|
||||||
|
# set for logged in users, cite:
|
||||||
|
# 'for anonymous comments only, set to None for logged in comments'
|
||||||
|
author_email = email
|
||||||
|
# /XXX
|
||||||
|
|
||||||
|
return author_name, author_email
|
||||||
|
|
||||||
|
def create_comment(self, data):
|
||||||
|
context = aq_inner(self.context)
|
||||||
|
comment = createObject('plone.Comment')
|
||||||
|
|
||||||
|
registry = queryUtility(IRegistry)
|
||||||
|
settings = registry.forInterface(IDiscussionSettings, check=False)
|
||||||
|
anonymous_comments = settings.anonymous_comments
|
||||||
|
|
||||||
|
# Set comment mime type to current setting in the discussion registry
|
||||||
|
comment.mime_type = settings.text_transform
|
||||||
|
|
||||||
|
# Set comment attributes (including extended comment form attributes)
|
||||||
|
for attribute in self.fields.keys():
|
||||||
|
setattr(comment, attribute, data[attribute])
|
||||||
|
|
||||||
|
# Set dates
|
||||||
|
comment.creation_date = datetime.utcnow()
|
||||||
|
comment.modification_date = datetime.utcnow()
|
||||||
|
|
||||||
|
# Get author name and email
|
||||||
|
comment.author_name, comment.author_email = self.get_author(data)
|
||||||
|
|
||||||
|
# Set comment author properties for anonymous users or members
|
||||||
|
portal_membership = getToolByName(context, 'portal_membership')
|
||||||
|
anon = portal_membership.isAnonymousUser()
|
||||||
|
if anon and anonymous_comments:
|
||||||
|
# Anonymous Users
|
||||||
|
comment.user_notification = None
|
||||||
|
elif not anon and getSecurityManager().checkPermission(
|
||||||
|
'Reply to item', context):
|
||||||
|
# Member
|
||||||
|
member = portal_membership.getAuthenticatedMember()
|
||||||
|
memberid = member.getId()
|
||||||
|
user = member.getUser()
|
||||||
|
comment.changeOwnership(user, recursive=False)
|
||||||
|
comment.manage_setLocalRoles(memberid, ['Owner'])
|
||||||
|
comment.creator = memberid
|
||||||
|
comment.author_username = memberid
|
||||||
|
|
||||||
|
else: # pragma: no cover
|
||||||
|
raise Unauthorized(
|
||||||
|
u'Anonymous user tries to post a comment, but anonymous '
|
||||||
|
u'commenting is disabled. Or user does not have the '
|
||||||
|
u"'reply to item' permission."
|
||||||
|
)
|
||||||
|
|
||||||
|
return comment
|
||||||
|
|
||||||
@button.buttonAndHandler(_(u'add_comment_button', default=u'Comment'),
|
@button.buttonAndHandler(_(u'add_comment_button', default=u'Comment'),
|
||||||
name='comment')
|
name='comment')
|
||||||
def handleComment(self, action):
|
def handleComment(self, action):
|
||||||
@ -178,74 +266,8 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
|||||||
None)
|
None)
|
||||||
captcha.validate(data['captcha'])
|
captcha.validate(data['captcha'])
|
||||||
|
|
||||||
# some attributes are not always set
|
|
||||||
author_name = u''
|
|
||||||
|
|
||||||
# Create comment
|
# Create comment
|
||||||
comment = createObject('plone.Comment')
|
comment = self.create_comment(data)
|
||||||
|
|
||||||
# Set comment mime type to current setting in the discussion registry
|
|
||||||
comment.mime_type = settings.text_transform
|
|
||||||
|
|
||||||
# Set comment attributes (including extended comment form attributes)
|
|
||||||
for attribute in self.fields.keys():
|
|
||||||
setattr(comment, attribute, data[attribute])
|
|
||||||
# Make sure author_name/ author_email is properly encoded
|
|
||||||
if 'author_name' in data:
|
|
||||||
author_name = data['author_name']
|
|
||||||
if isinstance(author_name, str):
|
|
||||||
author_name = unicode(author_name, 'utf-8')
|
|
||||||
if 'author_email' in data:
|
|
||||||
author_email = data['author_email']
|
|
||||||
if isinstance(author_email, str):
|
|
||||||
author_email = unicode(author_email, 'utf-8')
|
|
||||||
|
|
||||||
# Set comment author properties for anonymous users or members
|
|
||||||
can_reply = getSecurityManager().checkPermission('Reply to item',
|
|
||||||
context)
|
|
||||||
portal_membership = getToolByName(self.context, 'portal_membership')
|
|
||||||
if anon and anonymous_comments:
|
|
||||||
# Anonymous Users
|
|
||||||
comment.author_name = author_name
|
|
||||||
comment.author_email = author_email
|
|
||||||
comment.user_notification = None
|
|
||||||
comment.creation_date = datetime.utcnow()
|
|
||||||
comment.modification_date = datetime.utcnow()
|
|
||||||
elif not portal_membership.isAnonymousUser() and can_reply:
|
|
||||||
# Member
|
|
||||||
member = portal_membership.getAuthenticatedMember()
|
|
||||||
memberid = member.getId()
|
|
||||||
user = member.getUser()
|
|
||||||
email = member.getProperty('email')
|
|
||||||
fullname = member.getProperty('fullname')
|
|
||||||
if not fullname or fullname == '':
|
|
||||||
fullname = member.getUserName()
|
|
||||||
# memberdata is stored as utf-8 encoded strings
|
|
||||||
elif isinstance(fullname, str):
|
|
||||||
fullname = unicode(fullname, 'utf-8')
|
|
||||||
if email and isinstance(email, str):
|
|
||||||
email = unicode(email, 'utf-8')
|
|
||||||
comment.changeOwnership(user, recursive=False)
|
|
||||||
comment.manage_setLocalRoles(memberid, ['Owner'])
|
|
||||||
comment.creator = memberid
|
|
||||||
comment.author_username = memberid
|
|
||||||
comment.author_name = fullname
|
|
||||||
|
|
||||||
# XXX: according to IComment interface author_email must not be
|
|
||||||
# set for logged in users, cite:
|
|
||||||
# 'for anonymous comments only, set to None for logged in comments'
|
|
||||||
comment.author_email = email
|
|
||||||
# /XXX
|
|
||||||
|
|
||||||
comment.creation_date = datetime.utcnow()
|
|
||||||
comment.modification_date = datetime.utcnow()
|
|
||||||
|
|
||||||
else: # pragma: no cover
|
|
||||||
raise Unauthorized(
|
|
||||||
u'Anonymous user tries to post a comment, but anonymous '
|
|
||||||
u'commenting is disabled. Or user does not have the '
|
|
||||||
u"'reply to item' permission."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add comment to conversation
|
# Add comment to conversation
|
||||||
conversation = IConversation(self.__parent__)
|
conversation = IConversation(self.__parent__)
|
||||||
|
@ -8,6 +8,7 @@ from Products.CMFCore.interfaces import IFolderish
|
|||||||
from Products.CMFCore.utils import getToolByName
|
from Products.CMFCore.utils import getToolByName
|
||||||
from Products.CMFPlone.interfaces import INonStructuralFolder
|
from Products.CMFPlone.interfaces import INonStructuralFolder
|
||||||
from Products.CMFPlone.interfaces import IPloneSiteRoot
|
from Products.CMFPlone.interfaces import IPloneSiteRoot
|
||||||
|
from Products.CMFPlone.utils import safe_hasattr
|
||||||
from zope.component import queryUtility
|
from zope.component import queryUtility
|
||||||
|
|
||||||
|
|
||||||
@ -18,6 +19,20 @@ except ImportError:
|
|||||||
DEXTERITY_INSTALLED = False
|
DEXTERITY_INSTALLED = False
|
||||||
|
|
||||||
|
|
||||||
|
def traverse_parents(context):
|
||||||
|
# Run through the aq_chain of obj and check if discussion is
|
||||||
|
# enabled in a parent folder.
|
||||||
|
for obj in aq_chain(context):
|
||||||
|
if not IPloneSiteRoot.providedBy(obj):
|
||||||
|
obj_is_folderish = IFolderish.providedBy(obj)
|
||||||
|
obj_is_stuctural = not INonStructuralFolder.providedBy(obj)
|
||||||
|
if (obj_is_folderish and obj_is_stuctural):
|
||||||
|
flag = getattr(obj, 'allow_discussion', None)
|
||||||
|
if flag is not None:
|
||||||
|
return flag
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class ConversationView(object):
|
class ConversationView(object):
|
||||||
|
|
||||||
def enabled(self):
|
def enabled(self):
|
||||||
@ -30,14 +45,14 @@ class ConversationView(object):
|
|||||||
""" Returns True if discussion is enabled for this conversation.
|
""" Returns True if discussion is enabled for this conversation.
|
||||||
|
|
||||||
This method checks five different settings in order to figure out if
|
This method checks five different settings in order to figure out if
|
||||||
discussion is enable on a specific content object:
|
discussion is enabled on a specific content object:
|
||||||
|
|
||||||
1) Check if discussion is enabled globally in the plone.app.discussion
|
1) Check if discussion is enabled globally in the plone.app.discussion
|
||||||
registry/control panel.
|
registry/control panel.
|
||||||
|
|
||||||
2) If the current content object is a folder, always return
|
2) If the current content object is a folder, always return
|
||||||
False, since we don't allow comments on a folder. This
|
False, since we don't allow comments on a folder. This
|
||||||
setting is used to allow/ disallow comments for all content
|
setting is used to allow / disallow comments for all content
|
||||||
objects inside a folder, not for the folder itself.
|
objects inside a folder, not for the folder itself.
|
||||||
|
|
||||||
3) Check if the allow_discussion boolean flag on the content object is
|
3) Check if the allow_discussion boolean flag on the content object is
|
||||||
@ -62,23 +77,10 @@ class ConversationView(object):
|
|||||||
|
|
||||||
# Always return False if object is a folder
|
# Always return False if object is a folder
|
||||||
context_is_folderish = IFolderish.providedBy(context)
|
context_is_folderish = IFolderish.providedBy(context)
|
||||||
context_is_structural = not INonStructuralFolder.providedBy(context)
|
if context_is_folderish:
|
||||||
if (context_is_folderish and context_is_structural):
|
if not INonStructuralFolder.providedBy(context):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def traverse_parents(context):
|
|
||||||
# Run through the aq_chain of obj and check if discussion is
|
|
||||||
# enabled in a parent folder.
|
|
||||||
for obj in aq_chain(context):
|
|
||||||
if not IPloneSiteRoot.providedBy(obj):
|
|
||||||
obj_is_folderish = IFolderish.providedBy(obj)
|
|
||||||
obj_is_stuctural = not INonStructuralFolder.providedBy(obj)
|
|
||||||
if (obj_is_folderish and obj_is_stuctural):
|
|
||||||
flag = getattr(obj, 'allow_discussion', None)
|
|
||||||
if flag is not None:
|
|
||||||
return flag
|
|
||||||
return None
|
|
||||||
|
|
||||||
# If discussion is disabled for the object, bail out
|
# If discussion is disabled for the object, bail out
|
||||||
obj_flag = getattr(aq_base(context), 'allow_discussion', None)
|
obj_flag = getattr(aq_base(context), 'allow_discussion', None)
|
||||||
if obj_flag is False:
|
if obj_flag is False:
|
||||||
@ -132,7 +134,7 @@ class ConversationView(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Check if discussion is allowed on the content object
|
# Check if discussion is allowed on the content object
|
||||||
if hasattr(context, 'allow_discussion'):
|
if safe_hasattr(context, 'allow_discussion'):
|
||||||
if context.allow_discussion is not None:
|
if context.allow_discussion is not None:
|
||||||
return context.allow_discussion
|
return context.allow_discussion
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ except ImportError:
|
|||||||
try:
|
try:
|
||||||
from plone.app.contentrules.handlers import execute
|
from plone.app.contentrules.handlers import execute
|
||||||
except ImportError:
|
except ImportError:
|
||||||
execute = lambda context, event: False
|
def execute(context, event):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def execute_comment(event):
|
def execute_comment(event):
|
||||||
|
Loading…
Reference in New Issue
Block a user