diff --git a/plone/app/discussion/comment.py b/plone/app/discussion/comment.py
index 6bcfdcf..c9e7077 100644
--- a/plone/app/discussion/comment.py
+++ b/plone/app/discussion/comment.py
@@ -10,6 +10,7 @@ from smtplib import SMTPException
from zope.annotation.interfaces import IAnnotatable
+from zope.event import notify
from zope.component.factory import Factory
from zope.component import queryUtility
@@ -32,6 +33,11 @@ from OFS.Traversable import Traversable
from plone.registry.interfaces import IRegistry
+from plone.app.discussion.events import CommentAddedEvent
+from plone.app.discussion.events import CommentRemovedEvent
+from plone.app.discussion.events import ReplyAddedEvent
+from plone.app.discussion.events import ReplyRemovedEvent
+
from plone.app.discussion import PloneAppDiscussionMessageFactory as _
from plone.app.discussion.interfaces import IComment
from plone.app.discussion.interfaces import IConversation
@@ -232,7 +238,6 @@ def notify_content_object(obj, event):
'last_comment_date',
'commentators'))
-
def notify_content_object_deleted(obj, event):
"""Remove all comments of a content object when the content object has been
deleted.
@@ -242,6 +247,19 @@ def notify_content_object_deleted(obj, event):
while conversation:
del conversation[conversation.keys()[0]]
+def notify_comment_added(obj, event):
+ """ Notify custom discussion events when a comment is added or replied
+ """
+ if getattr(obj, 'in_reply_to', None):
+ return notify(ReplyAddedEvent(obj))
+ return notify(CommentAddedEvent(obj))
+
+def notify_comment_removed(obj, event):
+ """ Notify custom discussion events when a comment or reply is removed
+ """
+ if getattr(obj, 'in_reply_to', None):
+ return notify(ReplyRemovedEvent(obj))
+ return notify(CommentRemovedEvent(obj))
def notify_content_object_moved(obj, event):
"""Update all comments of a content object that has been moved.
diff --git a/plone/app/discussion/configure.zcml b/plone/app/discussion/configure.zcml
index ed82463..c3345f7 100644
--- a/plone/app/discussion/configure.zcml
+++ b/plone/app/discussion/configure.zcml
@@ -14,6 +14,7 @@
+
diff --git a/plone/app/discussion/contentrules.py b/plone/app/discussion/contentrules.py
new file mode 100644
index 0000000..eb46890
--- /dev/null
+++ b/plone/app/discussion/contentrules.py
@@ -0,0 +1,42 @@
+""" Content rules handlers
+"""
+from Acquisition import aq_parent
+from plone.app.contentrules.handlers import execute
+from plone.stringinterp import adapters
+
+def execute_comment(event):
+ """ Execute comment content rules
+ """
+ execute(event.object, event)
+
+#
+# String interp for comment's content rules
+#
+class Mixin(object):
+ """ Override context
+ """
+ @property
+ def context(self):
+ """ Getter
+ """
+ conversation = aq_parent(self._context)
+ return aq_parent(conversation)
+
+ @context.setter
+ def context(self, value):
+ """ Setter
+ """
+ self._context = value
+
+
+class CommentUrlSubstitution(adapters.UrlSubstitution, Mixin):
+ """ Override context to be used for URL substitution
+ """
+
+class CommentParentUrlSubstitution(adapters.ParentUrlSubstitution, Mixin):
+ """ Override context to be used for Parent URL substitution
+ """
+
+class CommentIdSubstitution(adapters.IdSubstitution, Mixin):
+ """ Override context to be used for Id substitution
+ """
diff --git a/plone/app/discussion/contentrules.zcml b/plone/app/discussion/contentrules.zcml
new file mode 100644
index 0000000..b7f0353
--- /dev/null
+++ b/plone/app/discussion/contentrules.zcml
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plone/app/discussion/events.py b/plone/app/discussion/events.py
new file mode 100644
index 0000000..ec60da0
--- /dev/null
+++ b/plone/app/discussion/events.py
@@ -0,0 +1,38 @@
+""" Custom discussion events
+"""
+from zope.interface import implements
+from plone.app.discussion.interfaces import IDiscussionEvent
+from plone.app.discussion.interfaces import ICommentAddedEvent
+from plone.app.discussion.interfaces import ICommentRemovedEvent
+from plone.app.discussion.interfaces import IReplyAddedEvent
+from plone.app.discussion.interfaces import IReplyRemovedEvent
+
+class DiscussionEvent(object):
+ """ Custom event
+ """
+ implements(IDiscussionEvent)
+
+ def __init__(self, context, **kwargs):
+ self.object = context
+ for key, value in kwargs.items():
+ setattr(self, key, value)
+
+class CommentAddedEvent(DiscussionEvent):
+ """ Event to be triggered when a Comment is added
+ """
+ implements(ICommentAddedEvent)
+
+class CommentRemovedEvent(DiscussionEvent):
+ """ Event to be triggered when a Comment is removed
+ """
+ implements(ICommentRemovedEvent)
+
+class ReplyAddedEvent(DiscussionEvent):
+ """ Event to be triggered when a Comment reply is added
+ """
+ implements(IReplyAddedEvent)
+
+class ReplyRemovedEvent(DiscussionEvent):
+ """ Event to be triggered when a Comment reply is removed
+ """
+ implements(IReplyRemovedEvent)
diff --git a/plone/app/discussion/interfaces.py b/plone/app/discussion/interfaces.py
index 01d58b7..c39b8c5 100644
--- a/plone/app/discussion/interfaces.py
+++ b/plone/app/discussion/interfaces.py
@@ -4,6 +4,7 @@
from zope.interface import Interface
from zope.interface.common.mapping import IIterableMapping
+from zope.component.interfaces import IObjectEvent
from zope import schema
from plone.app.discussion import PloneAppDiscussionMessageFactory as _
@@ -345,3 +346,27 @@ class ICommentingTool(Interface):
This can be removed once we no longer support upgrading from versions
of Plone that had a portal_discussion tool.
"""
+
+#
+# Custom events
+#
+
+class IDiscussionEvent(IObjectEvent):
+ """ Discussion custom event
+ """
+
+class ICommentAddedEvent(IDiscussionEvent):
+ """ Comment added
+ """
+
+class ICommentRemovedEvent(IDiscussionEvent):
+ """ Comment removed
+ """
+
+class IReplyAddedEvent(IDiscussionEvent):
+ """ Comment reply added
+ """
+
+class IReplyRemovedEvent(IDiscussionEvent):
+ """ Comment reply removed
+ """
diff --git a/plone/app/discussion/subscribers.zcml b/plone/app/discussion/subscribers.zcml
index e563f80..12a30a5 100644
--- a/plone/app/discussion/subscribers.zcml
+++ b/plone/app/discussion/subscribers.zcml
@@ -15,12 +15,24 @@
handler=".comment.notify_content_object"
/>
+
+
+
+