From 8fb254f73d812cf950e18be373a3d6c95082e34d Mon Sep 17 00:00:00 2001 From: Timo Stollenwerk Date: Sat, 13 Jun 2009 16:46:37 +0000 Subject: [PATCH] add optional workflow actions to the get_replies method of the comments viewlet. switch from Acquisition.explicit to Acquisition.implicit for the comment class. adjust test_comment to work with Acquisition.implicit. svn path=/plone.app.discussion/trunk/; revision=27406 --- plone/app/discussion/browser/comments.pt | 5 +- plone/app/discussion/browser/comments.py | 28 ++++++++--- plone/app/discussion/comment.py | 46 +++++++++---------- plone/app/discussion/conversation.py | 2 +- plone/app/discussion/tests/test_comment.py | 2 +- .../app/discussion/tests/test_conversation.py | 6 +++ 6 files changed, 55 insertions(+), 34 deletions(-) diff --git a/plone/app/discussion/browser/comments.pt b/plone/app/discussion/browser/comments.pt index d263752..9d68d4c 100644 --- a/plone/app/discussion/browser/comments.pt +++ b/plone/app/discussion/browser/comments.pt @@ -1,8 +1,9 @@ diff --git a/plone/app/discussion/browser/comments.py b/plone/app/discussion/browser/comments.py index c34a04c..a455e47 100644 --- a/plone/app/discussion/browser/comments.py +++ b/plone/app/discussion/browser/comments.py @@ -8,7 +8,7 @@ from zope.component import createObject, getMultiAdapter, queryUtility from zope.viewlet.interfaces import IViewlet -from Acquisition import aq_inner, aq_parent +from Acquisition import aq_inner, aq_parent, aq_base from AccessControl import getSecurityManager @@ -21,7 +21,7 @@ from plone.registry.interfaces import IRegistry from plone.app.layout.viewlets.common import ViewletBase -from plone.app.discussion.interfaces import IComment, IReplies, IDiscussionSettings +from plone.app.discussion.interfaces import IConversation, IComment, IReplies, IDiscussionSettings from plone.app.discussion.conversation import conversationAdapterFactory from plone.app.discussion.comment import CommentFactory @@ -60,14 +60,28 @@ class CommentsViewlet(ViewletBase): conversation = conversationAdapterFactory(self.context) return conversation.enabled - def get_replies(self): - # Return all direct replies - conversation = conversationAdapterFactory(self.context) + def get_replies(self, workflow_actions=False): + # Acquisition wrap the conversation + context = aq_inner(self.context) + conversation = IConversation(context) + conversation = IConversation(context).__of__(context) + + # Return all direct replies if conversation.total_comments > 0: - return conversation.getThreads() + if workflow_actions: + # Return dict with workflow actions + #context = aq_inner(self.context) + wf = getToolByName(context, 'portal_workflow') + + for r in conversation.getThreads(): + comment_obj = r['comment'] + actions = wf.listActionInfos(object=comment_obj) + return conversation.getThreads() + else: + return conversation.getThreads() else: - return False + return [] def get_commenter_home_url(self, username): if username is None: diff --git a/plone/app/discussion/comment.py b/plone/app/discussion/comment.py index 4425033..848e6f8 100644 --- a/plone/app/discussion/comment.py +++ b/plone/app/discussion/comment.py @@ -4,7 +4,7 @@ from datetime import datetime from zope.interface import implements from zope.component.factory import Factory -from Acquisition import Explicit +from Acquisition import Implicit from OFS.Traversable import Traversable from AccessControl.Role import RoleManager from AccessControl.Owned import Owned @@ -14,75 +14,75 @@ from plone.app.discussion.interfaces import IComment from Products.CMFCore.DynamicType import DynamicType from Products.CMFCore.utils import getToolByName -class Comment(DynamicType, Traversable, RoleManager, Owned, Explicit): +class Comment(DynamicType, Traversable, RoleManager, Owned, Implicit): """A comment. - + This object attempts to be as lightweight as possible. We implement a number of standard methods instead of subclassing, to have total control over what goes into the object. """ - + implements(IComment) - + meta_type = portal_type = 'Discussion Item' - + __parent__ = None - + comment_id = None # long in_reply_to = None # long title = u"" - + mime_type = "text/plain" text = u"" - + creator = None creation_date = None modification_date = None - + author_username = None - + author_name = None author_email = None - - # Note: we want to use zope.component.createObject() to instantiate + + # Note: we want to use zope.component.createObject() to instantiate # comments as far as possible. comment_id and __parent__ are set via # IConversation.addComment(). - + def __init__(self): self.creation_date = self.modification_date = datetime.now() - + @property def __name__(self): return self.comment_id and unicode(self.comment_id) or None - + @property def id(self): return self.comment_id and str(self.comment_id) or None - + def getId(self): """The id of the comment, as a string """ return self.id - + def Title(self): """The title of the comment """ return self.title - + def Creator(self): """The name of the person who wrote the comment """ return self.creator - + # CMF's event handlers assume any IDynamicType has these :( - + def opaqueItems(self): return [] - + def opaqueIds(self): return [] - + def opaqueValues(self): return [] diff --git a/plone/app/discussion/conversation.py b/plone/app/discussion/conversation.py index 66762f9..e6ca4af 100644 --- a/plone/app/discussion/conversation.py +++ b/plone/app/discussion/conversation.py @@ -143,7 +143,7 @@ class Conversation(Traversable, Persistent, Explicit): def recurse(comment_id, d=0): # Yield the current comment before we look for its children - yield {'id': comment_id, 'comment': self._comments[comment_id], 'depth': d} + yield {'id': comment_id, 'comment': self[comment_id], 'depth': d} # Recurse if there are children and we are not out of our depth if depth is None or d + 1 < depth: diff --git a/plone/app/discussion/tests/test_comment.py b/plone/app/discussion/tests/test_comment.py index ee69f7d..c051cc7 100644 --- a/plone/app/discussion/tests/test_comment.py +++ b/plone/app/discussion/tests/test_comment.py @@ -56,7 +56,7 @@ class CommentTest(PloneTestCase): self.assertEquals('Comment 1', comment.title) self.assertEquals(('', 'plone', 'doc1', '++conversation++default', str(new_comment1_id)), comment.getPhysicalPath()) - self.assertEquals('plone/doc1/%2B%2Bconversation%2B%2Bdefault/' + str(new_comment1_id), comment.absolute_url()) + self.assertEquals('http://nohost/plone/doc1/++conversation++default/' + str(new_comment1_id), comment.absolute_url()) def test_workflow(self): self.portal.portal_workflow.setChainForPortalTypes(('Discussion Item',), ('simple_publication_workflow,')) diff --git a/plone/app/discussion/tests/test_conversation.py b/plone/app/discussion/tests/test_conversation.py index 2d79d01..731107c 100644 --- a/plone/app/discussion/tests/test_conversation.py +++ b/plone/app/discussion/tests/test_conversation.py @@ -541,8 +541,14 @@ class ConversationTest(PloneTestCase): # Create a conversation. conversation = IConversation(self.portal.doc1) + # Pretend that we have traversed to the comment by aq wrapping it. + conversation = conversation.__of__(self.portal.doc1) + # Check the parent self.failUnless(conversation.__parent__) + self.failUnless(aq_parent(conversation)) + # Todo: This one is failing! + #self.failUnless(conversation.REQUEST) self.assertEquals(conversation.__parent__.getId(), 'doc1') def test_discussion_item_not_in_bad_types(self):