Delete children when deleting a parent comment.
svn path=/plone.app.discussion/trunk/; revision=27092
This commit is contained in:
parent
a1e11cb5ee
commit
9263a61a31
@ -196,7 +196,7 @@ class Conversation(Traversable, Persistent, Explicit):
|
|||||||
"""
|
"""
|
||||||
return self._comments[long(key)].__of__(self)
|
return self._comments[long(key)].__of__(self)
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key, suppress_container_modified=False):
|
||||||
"""Delete an item by its long key
|
"""Delete an item by its long key
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -207,15 +207,36 @@ class Conversation(Traversable, Persistent, Explicit):
|
|||||||
|
|
||||||
notify(ObjectWillBeRemovedEvent(comment, self, key))
|
notify(ObjectWillBeRemovedEvent(comment, self, key))
|
||||||
|
|
||||||
self._comments.pop(key)
|
# Remove all children
|
||||||
notify(ObjectRemovedEvent(comment, self, key))
|
for child_id in self._children.get(key, []):
|
||||||
|
# avoid sending ContainerModifiedEvent multiple times
|
||||||
|
self.__delitem__(child_id, suppress_container_modified=True)
|
||||||
|
|
||||||
|
# XXX: During the events sent from the recursive deletion, the
|
||||||
|
# _children data structure may be in an inconsistent state. We may
|
||||||
|
# need to delay sending the events until it is fixed up.
|
||||||
|
|
||||||
|
# Remove the comment from _comments
|
||||||
|
self._comments.pop(key)
|
||||||
|
|
||||||
|
# Remove this comment as a child of its parent
|
||||||
|
if not suppress_container_modified:
|
||||||
|
parent = comment.in_reply_to
|
||||||
|
if parent is not None:
|
||||||
|
parent_children = self._children.get(parent, None)
|
||||||
|
if parent_children is not None and key in parent_children:
|
||||||
|
parent_children.remove(key)
|
||||||
|
|
||||||
|
# Remove commentators
|
||||||
if commentator and commentator in self._commentators:
|
if commentator and commentator in self._commentators:
|
||||||
if self._commentators[commentator] <= 1:
|
if self._commentators[commentator] <= 1:
|
||||||
del self._commentators[commentator]
|
del self._commentators[commentator]
|
||||||
else:
|
else:
|
||||||
self._commentators[commentator] -= 1
|
self._commentators[commentator] -= 1
|
||||||
|
|
||||||
|
notify(ObjectRemovedEvent(comment, self, key))
|
||||||
|
|
||||||
|
if not suppress_container_modified:
|
||||||
notify(ContainerModifiedEvent(self))
|
notify(ContainerModifiedEvent(self))
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
|
@ -81,6 +81,75 @@ class ConversationTest(PloneTestCase):
|
|||||||
# self.assertEquals(len(conversation.getThreads()), 0)
|
# self.assertEquals(len(conversation.getThreads()), 0)
|
||||||
self.assertEquals(conversation.total_comments, 0)
|
self.assertEquals(conversation.total_comments, 0)
|
||||||
|
|
||||||
|
def test_delete_recursive(self):
|
||||||
|
# Create a conversation. In this case we doesn't assign it to an
|
||||||
|
# object, as we just want to check the Conversation object API.
|
||||||
|
conversation = IConversation(self.portal.doc1)
|
||||||
|
|
||||||
|
# Pretend that we have traversed to the comment by aq wrapping it.
|
||||||
|
conversation = conversation.__of__(self.portal.doc1)
|
||||||
|
|
||||||
|
replies = IReplies(conversation)
|
||||||
|
|
||||||
|
# Create a nested comment structure:
|
||||||
|
#
|
||||||
|
# Conversation
|
||||||
|
# +- Comment 1
|
||||||
|
# +- Comment 1_1
|
||||||
|
# | +- Comment 1_1_1
|
||||||
|
# +- Comment 1_2
|
||||||
|
# +- Comment 2
|
||||||
|
# +- Comment 2_1
|
||||||
|
|
||||||
|
# Create all comments
|
||||||
|
comment1 = createObject('plone.Comment')
|
||||||
|
comment1.title = 'Comment 1'
|
||||||
|
comment1.text = 'Comment text'
|
||||||
|
|
||||||
|
comment1_1 = createObject('plone.Comment')
|
||||||
|
comment1_1.title = 'Re: Comment 1'
|
||||||
|
comment1_1.text = 'Comment text'
|
||||||
|
|
||||||
|
comment1_1_1 = createObject('plone.Comment')
|
||||||
|
comment1_1_1.title = 'Re: Re: Comment 1'
|
||||||
|
comment1_1_1.text = 'Comment text'
|
||||||
|
|
||||||
|
comment1_2 = createObject('plone.Comment')
|
||||||
|
comment1_2.title = 'Re: Comment 1 (2)'
|
||||||
|
comment1_2.text = 'Comment text'
|
||||||
|
|
||||||
|
comment2 = createObject('plone.Comment')
|
||||||
|
comment2.title = 'Comment 2'
|
||||||
|
comment2.text = 'Comment text'
|
||||||
|
|
||||||
|
comment2_1 = createObject('plone.Comment')
|
||||||
|
comment2_1.title = 'Re: Comment 2'
|
||||||
|
comment2_1.text = 'Comment text'
|
||||||
|
|
||||||
|
# Create the nested comment structure
|
||||||
|
new_id_1 = conversation.addComment(comment1)
|
||||||
|
new_id_2 = conversation.addComment(comment2)
|
||||||
|
|
||||||
|
comment1_1.in_reply_to = new_id_1
|
||||||
|
new_id_1_1 = conversation.addComment(comment1_1)
|
||||||
|
|
||||||
|
comment1_1_1.in_reply_to = new_id_1_1
|
||||||
|
new_id_1_1_1 = conversation.addComment(comment1_1_1)
|
||||||
|
|
||||||
|
comment1_2.in_reply_to = new_id_1
|
||||||
|
new_id_1_2 = conversation.addComment(comment1_2)
|
||||||
|
|
||||||
|
comment2_1.in_reply_to = new_id_2
|
||||||
|
new_id_2_1 = conversation.addComment(comment2_1)
|
||||||
|
|
||||||
|
del conversation[new_id_1]
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
[{'comment': comment2, 'depth': 0, 'id': new_id_2},
|
||||||
|
{'comment': comment2_1, 'depth': 1, 'id': new_id_2_1},
|
||||||
|
], list(conversation.getThreads()))
|
||||||
|
|
||||||
|
|
||||||
def test_dict_operations(self):
|
def test_dict_operations(self):
|
||||||
# test dict operations and acquisition wrapping
|
# test dict operations and acquisition wrapping
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user