Don't use session at all for content rules, set the event in the request to be able to access comment attributes. This fixes 'InvalidObjectReference: A new object is reachable from multiple databases.' if comment contains a RichTextValue which contains a RawValueHolder (persistent object).

This commit is contained in:
Vincent Fretin 2014-09-20 14:14:19 +02:00
parent fa127ad85c
commit 42d12200a7
3 changed files with 13 additions and 31 deletions

View File

@ -28,22 +28,18 @@ class CommentSubstitution(BaseSubstitution):
""" """
def __init__(self, context, **kwargs): def __init__(self, context, **kwargs):
super(CommentSubstitution, self).__init__(context, **kwargs) super(CommentSubstitution, self).__init__(context, **kwargs)
self._session = None
@property @property
def session(self): def event(self):
""" User session """ event that triggered the content rule
""" """
if self._session is None: return self.context.REQUEST.get('event')
sdm = getattr(self.context, 'session_data_manager', None)
self._session = sdm.getSessionData(create=False) if sdm else {}
return self._session
@property @property
def comment(self): def comment(self):
""" Get changed inline comment """ Get changed inline comment
""" """
return self.session.get('comment', {}) return self.event.comment
class Id(CommentSubstitution): class Id(CommentSubstitution):
""" Comment id string substitution """ Comment id string substitution
@ -54,7 +50,7 @@ class Id(CommentSubstitution):
def safe_call(self): def safe_call(self):
""" Safe call """ Safe call
""" """
return self.comment.get('comment_id', u'') return getattr(self.comment, 'comment_id', u'')
class Text(CommentSubstitution): class Text(CommentSubstitution):
""" Comment text """ Comment text
@ -65,7 +61,7 @@ class Text(CommentSubstitution):
def safe_call(self): def safe_call(self):
""" Safe call """ Safe call
""" """
return self.comment.get('text', u'') return getattr(self.comment, 'text', u'')
class AuthorUserName(CommentSubstitution): class AuthorUserName(CommentSubstitution):
""" Comment author user name string substitution """ Comment author user name string substitution
@ -76,7 +72,7 @@ class AuthorUserName(CommentSubstitution):
def safe_call(self): def safe_call(self):
""" Safe call """ Safe call
""" """
return self.comment.get('author_username', u'') return getattr(self.comment, 'author_username', u'')
class AuthorFullName(CommentSubstitution): class AuthorFullName(CommentSubstitution):
""" Comment author full name string substitution """ Comment author full name string substitution
@ -87,7 +83,7 @@ class AuthorFullName(CommentSubstitution):
def safe_call(self): def safe_call(self):
""" Safe call """ Safe call
""" """
return self.comment.get('author_name', u'') return getattr(self.comment, 'author_name', u'')
class AuthorEmail(CommentSubstitution): class AuthorEmail(CommentSubstitution):
""" Comment author email string substitution """ Comment author email string substitution
@ -98,4 +94,4 @@ class AuthorEmail(CommentSubstitution):
def safe_call(self): def safe_call(self):
""" Safe call """ Safe call
""" """
return self.comment.get('author_email', u'') return getattr(self.comment, 'author_email', u'')

View File

@ -19,16 +19,10 @@ class DiscussionEvent(object):
for key, value in kwargs.items(): for key, value in kwargs.items():
setattr(self, key, value) setattr(self, key, value)
# Add comment on session to easily define content-rules dynamic strings # Add event to the request to be able to access comment attributes
sdm = getattr(context, 'session_data_manager', None) # in content-rules dynamic strings
session = sdm.getSessionData(create=True) if sdm else None request = context.REQUEST
request.set('event', self)
if session:
sessionComment = dict(
(field, getattr(comment, field, None)) for field in IComment
if not field.startswith('_')
)
session.set('comment', sessionComment)
class CommentAddedEvent(DiscussionEvent): class CommentAddedEvent(DiscussionEvent):
""" Event to be triggered when a Comment is added """ Event to be triggered when a Comment is added

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import unittest2 as unittest import unittest2 as unittest
from Testing import ZopeTestCase as ztc
from zope.component import createObject, getAdapter from zope.component import createObject, getAdapter
from zope.event import notify
from plone.app.testing import TEST_USER_ID, setRoles from plone.app.testing import TEST_USER_ID, setRoles
from plone.contentrules.rule.interfaces import IRuleEventType from plone.contentrules.rule.interfaces import IRuleEventType
@ -25,9 +23,6 @@ class CommentContentRulesTest(unittest.TestCase):
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
def setUp(self): def setUp(self):
# Setup session manager
ztc.utils.setupCoreSessions(self.layer['app'])
# Setup sandbox # Setup sandbox
self.portal = self.layer['portal'] self.portal = self.layer['portal']
self.request = self.layer['request'] self.request = self.layer['request']
@ -94,9 +89,6 @@ class ReplyContentRulesTest(unittest.TestCase):
layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING layer = PLONE_APP_DISCUSSION_INTEGRATION_TESTING
def setUp(self): def setUp(self):
# Setup session manager
ztc.utils.setupCoreSessions(self.layer['app'])
# Setup sandbox # Setup sandbox
self.portal = self.layer['portal'] self.portal = self.layer['portal']
self.request = self.layer['request'] self.request = self.layer['request']