This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
tabellio.contact/tabellio/contact/form.py

208 lines
7.5 KiB
Python

from five import grok
from Acquisition import aq_inner
from zope.interface import implements
from zope import interface, schema, component
from zope.component import getMultiAdapter, provideAdapter
from Products.CMFCore.utils import getToolByName
from z3c.form import form, field, button, validator
from plone.z3cform.layout import wrap_form
from z3c.form.ptcompat import ViewPageTemplateFile
from plone.dexterity.content import Item
from plone.formwidget.captcha.widget import CaptchaFieldWidget
from plone.formwidget.captcha.validator import CaptchaValidator
from zope.schema import ValidationError
from zope.schema.interfaces import IContextSourceBinder
from zope.schema.vocabulary import SimpleVocabulary
from plone.registry.interfaces import IRegistry
from tabellio.config.interfaces import ITabellioSettings
from tabellio.contact.interfaces import MessageFactory as _
class IContactForm(interface.Interface):
title = schema.TextLine(title=_(u'Title'))
description = schema.Text(title=_(u'Description'))
subjects = schema.Text(title=_(u'Available Subjects'))
class ContactForm(Item):
implements(IContactForm)
class View(grok.View):
grok.context(IContactForm)
grok.require('zope2.View')
def contact_form(self):
effective_contact = EffectiveContact(self.context)
effective_form = EffectiveContactForm(effective_contact, self.request)
effective_form.update()
return effective_form.render()
@grok.provider(IContextSourceBinder)
def get_possible_subjects(context):
terms = []
for line in context.context.subjects.splitlines():
try:
topic, email = line.strip().split('|')
except ValueError:
continue
if email == '->deputy':
terms.append(SimpleVocabulary.createTerm('-deputy', '-deputy', topic))
else:
terms.append(SimpleVocabulary.createTerm(topic, topic.encode('ascii', 'replace'), topic))
if len(terms) == 0:
terms.append(SimpleVocabulary.createTerm('-', '-', '-'))
return SimpleVocabulary(terms)
class IEffectiveContact(interface.Interface):
subject = schema.Choice(title=_(u'Subject'), required=True,
source=get_possible_subjects)
name = schema.TextLine(title=_(u'Name'), required=True)
email = schema.TextLine(title=_(u'Email'), required=True)
phone = schema.TextLine(title=_(u'Phone'), required=False)
message = schema.Text(title=_(u'Message'), required=True)
captcha = schema.TextLine(title=u'Captcha', required=False)
class EffectiveContact(object):
implements(IEffectiveContact)
def __init__(self, context=None):
self.context = context
def absolute_url(self):
# this is used by the captcha
return self.context.absolute_url()
class EffectiveContactForm(form.Form):
fields = field.Fields(IEffectiveContact)
fields['captcha'].widgetFactory = CaptchaFieldWidget
template = ViewPageTemplateFile('form_templates/view_effectivecontact.pt')
def updateWidgets(self):
super(EffectiveContactForm, self).updateWidgets()
self.widgets['message'].rows = 10
@button.buttonAndHandler(_(u'Send'))
def handleApply(self, action):
data, errors = self.extractData()
if not errors and data.has_key('captcha'):
# Verify the user input against the captcha
try:
captcha = CaptchaValidator(self.context, self.request, None, IEffectiveContact['captcha'], None)
if captcha.validate(data['captcha']):
# if captcha validation passes, send the email.
plone_utils = getToolByName(self.context.context, 'plone_utils')
plone_utils.addPortalMessage(_(u'Your message has been sent successfully.'))
portal = getToolByName(self.context.context, 'portal_url').getPortalObject()
return self.request.response.redirect(portal.absolute_url())
except ValidationError:
pass
return
def cmp_person(x, y):
t = cmp(x.lastname.lower(), y.lastname.lower())
if t: return t
return cmp(x.firstname.lower(), y.lastname.lower())
@grok.provider(IContextSourceBinder)
def get_deputies(context):
portal = getToolByName(context.context, 'portal_url').getPortalObject()
settings = component.getUtility(IRegistry).forInterface(ITabellioSettings, False)
path = settings.deputiesPath
current = portal
for part in settings.deputiesPath.split('/'):
if not part:
continue
current = getattr(current, part)
deputies = []
for object in current.objectValues():
if object.portal_type != 'themis.datatypes.deputy':
continue
if not object.active:
continue
deputies.append(object)
deputies.sort(cmp_person)
terms = []
for deputy in deputies:
deputy_id = deputy.getId()
terms.append(SimpleVocabulary.createTerm(deputy_id, deputy_id, deputy.Title()))
return SimpleVocabulary(terms)
class Deputy(grok.View):
grok.context(IContactForm)
grok.require('zope2.View')
grok.name('deputy')
def deputy_contact_form(self):
effective_contact = EffectiveDeputyContact(self.context)
effective_form = EffectiveDeputyContactForm(effective_contact, self.request)
effective_form.update()
return effective_form.render()
class IEffectiveDeputyContact(interface.Interface):
deputy = schema.Choice(title=_(u'Deputy'), required=True,
source=get_deputies)
subject = schema.TextLine(title=_(u'Subject'), required=True)
name = schema.TextLine(title=_(u'Name'), required=True)
email = schema.TextLine(title=_(u'Email'), required=True)
phone = schema.TextLine(title=_(u'Phone'), required=False)
message = schema.Text(title=_(u'Message'), required=True)
captcha = schema.TextLine(title=u'Captcha', required=False)
class EffectiveDeputyContact(object):
implements(IEffectiveDeputyContact)
def __init__(self, context=None):
self.context = context
def absolute_url(self):
# this is used by the captcha
return self.context.absolute_url()
class EffectiveDeputyContactForm(form.Form):
fields = field.Fields(IEffectiveDeputyContact)
fields['captcha'].widgetFactory = CaptchaFieldWidget
template = ViewPageTemplateFile('form_templates/view_effectivedeputycontact.pt')
def updateWidgets(self):
super(EffectiveDeputyContactForm, self).updateWidgets()
self.widgets['message'].rows = 10
@button.buttonAndHandler(_(u'Send'))
def handleApply(self, action):
data, errors = self.extractData()
if not errors and data.has_key('captcha'):
# Verify the user input against the captcha
try:
captcha = CaptchaValidator(self.context, self.request, None, IEffectiveContact['captcha'], None)
if captcha.validate(data['captcha']):
# if captcha validation passes, send the email.
plone_utils = getToolByName(self.context.context, 'plone_utils')
plone_utils.addPortalMessage(_(u'Your message has been sent successfully.'))
portal = getToolByName(self.context.context, 'portal_url').getPortalObject()
return self.request.response.redirect(portal.absolute_url())
except ValidationError:
pass
return
# Register Captcha validator for the captcha field in the IContactForm
validator.WidgetValidatorDiscriminators(CaptchaValidator, field=IEffectiveContact['captcha'])