diff --git a/plone/app/discussion/browser/captcha.py b/plone/app/discussion/browser/captcha.py index a0e3105..36e216c 100644 --- a/plone/app/discussion/browser/captcha.py +++ b/plone/app/discussion/browser/captcha.py @@ -7,21 +7,23 @@ from zope import interface, schema from zope.annotation import factory from zope.annotation.attribute import AttributeAnnotations -from zope.component import adapts, provideAdapter - +from zope.component import adapts, provideAdapter, queryUtility from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.interface import Interface, implements +from plone.registry.interfaces import IRegistry + from plone.z3cform.fieldsets import extensible from plone.z3cform.fieldsets.interfaces import IFormExtender -from plone.app.discussion.comment import Comment from plone.app.discussion.browser.comments import CommentForm +from plone.app.discussion.comment import Comment +from plone.app.discussion.interfaces import IDiscussionSettings class ICaptcha(Interface): - captcha = schema.TextLine(title=u"Type the word 'human' in all capital letters.", - required=False) + captcha = schema.TextLine(title=u"Captcha", + required=True) class Captcha(Persistent): interface.implements(ICaptcha) @@ -40,6 +42,15 @@ class CaptchaExtender(extensible.FormExtender): self.request = request self.form = form + registry = queryUtility(IRegistry) + settings = registry.forInterface(IDiscussionSettings) + self.captcha = settings.captcha + def update(self): - # Add all fields from the captcha interface - self.add(ICaptcha, prefix="extra") \ No newline at end of file + if self.captcha != 'disabled': + # Add all fields from the captcha interface + self.add(ICaptcha, prefix="") + if self.captcha == 'captcha': + self.form.fields['captcha'].widgetFactory = CaptchaFieldWidget + elif self.captcha == 'recaptcha': + self.form.fields['captcha'].widgetFactory = ReCaptchaFieldWidget \ No newline at end of file diff --git a/plone/app/discussion/configure.zcml b/plone/app/discussion/configure.zcml index 4c5e1d0..4c6aa72 100644 --- a/plone/app/discussion/configure.zcml +++ b/plone/app/discussion/configure.zcml @@ -71,6 +71,10 @@ handler=".tool.unindex_object" /> + + + @@ -89,4 +93,4 @@ - + \ No newline at end of file diff --git a/plone/app/discussion/interfaces.py b/plone/app/discussion/interfaces.py index f12c80f..b87bfd9 100644 --- a/plone/app/discussion/interfaces.py +++ b/plone/app/discussion/interfaces.py @@ -25,6 +25,14 @@ class IDiscussionSettings(Interface): description=_(u"Use this setting to enable or disable posting comments as anonymous visitor."), default=False) + captcha = schema.Choice(title=_(u"Captcha"), + description=_(u"""Use this setting to enable or disable captcha validation for comments. + If no captcha options are available, install captcha solutions like + plone.formwidget.captcha or plone.formwidget.recaptcha."""), + required=True, + default='disabled', + vocabulary='plone.app.discussion.vocabularies.CaptchaVocabulary',) + show_commenter_image = schema.Bool(title=_(u"Show commenter image"), description=_(u"Use this setting to enable or disable showing the commenter's image next to his/her comments."), default=True) diff --git a/plone/app/discussion/tests/test_controlpanel.py b/plone/app/discussion/tests/test_controlpanel.py index c6c3e60..88f231a 100644 --- a/plone/app/discussion/tests/test_controlpanel.py +++ b/plone/app/discussion/tests/test_controlpanel.py @@ -1,5 +1,7 @@ import unittest +from zope.component import getMultiAdapter + from plone.registry import Registry from Products.CMFCore.utils import getToolByName @@ -31,6 +33,13 @@ class RegistryTest(PloneTestCase): self.failUnless('globally_enabled' in IDiscussionSettings) self.assertEquals(self.registry['plone.app.discussion.interfaces.IDiscussionSettings.globally_enabled'], True) + def test_captcha(self): + # Check globally_enabled record + globally_enabled_record = self.registry.records['plone.app.discussion.interfaces.IDiscussionSettings.captcha'] + + self.failUnless('captcha' in IDiscussionSettings) + self.assertEquals(self.registry['plone.app.discussion.interfaces.IDiscussionSettings.captcha'], 'disabled') + def test_anonymous_comments(self): # Check anonymous_comments record anonymous_comments_record = self.registry.records['plone.app.discussion.interfaces.IDiscussionSettings.anonymous_comments'] diff --git a/plone/app/discussion/vocabularies.py b/plone/app/discussion/vocabularies.py new file mode 100644 index 0000000..155c8e7 --- /dev/null +++ b/plone/app/discussion/vocabularies.py @@ -0,0 +1,48 @@ +from zope import interface +from zope import component +import zope.schema.interfaces +import zope.schema.vocabulary + +# XXX: REPLACE THIS!!! +HAS_CAPTCHA=False +HAS_RECAPTCHA=False + +try: + from plone.formwidget.captcha.widget import CaptchaFieldWidget + HAS_CAPTCHA = True +except ImportError: + pass + +try: + from plone.formwidget.captcha.widget import ReCaptchaFieldWidget + HAS_RECAPTCHA = True +except ImportError: + pass +# XXX: REPLACE THIS!!! + +def captcha_vocabulary(context): + """Vocabulary with all available captcha implementations. + """ + terms = [] + terms.append( + zope.schema.vocabulary.SimpleTerm( + value='disabled', + token='disabled', + title='Disabled')) + + if HAS_CAPTCHA: + terms.append( + zope.schema.vocabulary.SimpleTerm( + value='captcha', + token='captcha', + title='Captcha')) + if HAS_RECAPTCHA: + terms.append( + zope.schema.vocabulary.SimpleTerm( + value='recaptcha', + token='recaptcha', + title='ReCaptcha')) + return zope.schema.vocabulary.SimpleVocabulary(terms) + +interface.alsoProvides(captcha_vocabulary, + zope.schema.interfaces.IVocabularyFactory) \ No newline at end of file