def fields(self): terms = [] for reg in getAllUtilitiesRegisteredFor(IRecipientSourceRegistration): if not reg.enabled: continue terms.append(schema.vocabulary.SimpleTerm( value = reg, token = reg.name, title = reg.title, )) # if only one source, redirect to it if len(terms) <= 1: self._redirect_url = '%s/@@add-recipient?form.widgets.recipient_type=%s' % (self.context.absolute_url(), terms[0].value.name) return field.Fields() vocab = schema.vocabulary.SimpleVocabulary(terms) fields = field.Fields(schema.Choice( __name__ = 'recipient_type', title = _(u'Recipient type'), description = _(u'Select the type of recipient you want to add.'), vocabulary = vocab, default = vocab.by_token['standard'].value, )) fields['recipient_type'].widgetFactory = DescriptiveRadioWidget return fields
def getVariables(self): fields = self.wizard.session['formfields']['fields'] ignored_fields = ('sincerely', ) vars = [('sender_%s' % f_id, _(u"Sender's $varname", mapping={'varname': f['title']})) for f_id, f in sorted(fields.items(), key=lambda x:x[1]['order']) if f_id not in ignored_fields] vars.append(('sender_public_name', _(u"Sender's first name and last initial"))) return [dict(title=title, id=id) for id, title in vars]
def add(self, data): data['order'] = len(self._get_fields()) id = getUtility(IIDNormalizer).normalize(data['title']) if id in self._get_fields().keys() or id in self.context.objectIds(): raise schema.ValidationError, _(u'You selected a field name that is already in use. Please use a different name.') self._get_fields()[id] = data self.wizard.sync() self.request._added_field = id return data
def getVariables(self): fields = self.wizard.session['formfields']['fields'] ignored_fields = ('sincerely', ) vars = [('sender_%s' % f_id, _(u"Sender's $varname", mapping={'varname': f['title']})) for f_id, f in sorted(fields.items(), key=lambda x:x[1]['order']) if f_id not in ignored_fields] vars += ( ('recip_honorific', _(u"Recipient's Honorific")), ('recip_first', _(u"Recipient's First")), ('recip_last', _(u"Recipient's Last")), ) return [dict(title=title, id=id) for id, title in vars]
def initialize(self): data = self.getContent() if 'subject' not in data: data['subject'] = utranslate(DOMAIN, _(u'Thanks for your participation, ${sender_first}'), context=self.request) if 'template' not in data: data['template'] = utranslate(DOMAIN, DEFAULT_THANKYOU_TEMPLATE, context=self.request) if 'thankyou_text' not in data: data['thankyou_text'] = utranslate(DOMAIN, _(u'Thank you for participating.'), context=self.request) self.wizard.sync()
def apply(self, pfg, initial_finish=True): """ Apply changes to the underlying PloneFormGen form based on the submitted values. """ data = self.getContent() existing_ids = pfg.objectIds() annotation = IAnnotations(pfg).setdefault(ANNOTATION_KEY, PersistentDict()) # store the recipient info in an annotation on the form annotation['recipients'] = data['recipients'] # create the multiplexing mailer if RECIPIENT_MAILER_ID not in existing_ids: pfg.invokeFactory(id=RECIPIENT_MAILER_ID, type_name='LetterRecipientMailerAdapter') adapters = list(pfg.actionAdapter) adapters.remove(RECIPIENT_MAILER_ID) pfg.setActionAdapter(adapters) mailer = getattr(pfg, RECIPIENT_MAILER_ID) mailer.setTitle(utranslate(DOMAIN, _(u'Emails to decision maker(s)'), context=self.request)) else: mailer = getattr(pfg, RECIPIENT_MAILER_ID) if mailer.getExecCondition != 'request/form/recip_email|nothing': mailer.setExecCondition('request/form/recip_email|nothing') if not mailer.getRawRecipientOverride(): mailer.setRecipientOverride('request/form/recip_email|nothing') formgen_tool = getToolByName(pfg, 'formgen_tool') if mailer.getRawBody_pt() == formgen_tool.getDefaultMailTemplateBody(): mailer.setBody_pt(LETTER_MAILTEMPLATE_BODY) execCondition = mailer.getRawExecCondition() if not execCondition or execCondition in ('request/form/recip_email|nothing', 'python:False'): mailer.setExecCondition(data['send_email'] and 'request/form/recip_email|nothing' or 'python:False')
def apply(self, pfg, initial_finish=True): data = self.getContent() if THANK_YOU_EMAIL_ID not in pfg.objectIds(): pfg.invokeFactory(id=THANK_YOU_EMAIL_ID, type_name="FormMailerAdapter") mailer = getattr(pfg, THANK_YOU_EMAIL_ID) mailer.setTitle(utranslate(DOMAIN, _(u"Thank you email to activist"), context=self.request)) else: mailer = getattr(pfg, THANK_YOU_EMAIL_ID) action_adapters = list(pfg.getActionAdapter()) if data['email'] and mailer.getId() not in action_adapters: action_adapters.append(mailer.getId()) elif not data['email'] and mailer.getId() in action_adapters: action_adapters.remove(mailer.getId()) pfg.setActionAdapter(action_adapters) if data.get("from_addr", None): mailer.setSenderOverride('string:' + data['from_addr']) if mailer.getTo_field() == '#NONE#': mailer.setTo_field('email') mailer.setMsg_subject(data['subject']) annotation = IAnnotations(pfg).setdefault(ANNOTATION_KEY, PersistentDict()) annotation['thankyou_template'] = data['template'] # replace default mail template body with our own version, unless its been customized formgen_tool = getToolByName(pfg, 'formgen_tool') if mailer.getRawBody_pt() == formgen_tool.getDefaultMailTemplateBody(): mailer.setBody_pt(THANKYOU_MAILTEMPLATE_BODY) if not mailer.getRawSubjectOverride(): mailer.setSubjectOverride('here/@@letter-mailer-renderer/render_subject') thankyou = getattr(pfg, 'thank-you', None) if thankyou is not None: thankyou.setThanksPrologue(data['thankyou_text']) if data['thankyou_url']: pfg.setThanksPageOverride('redirect_to:string:' + data['thankyou_url'])
def validate(self, value): super(MegaphoneFormTemplateVariableValidator, self).validate(value) valid_fields = set(['sender_%s' % f for f in self.view.wizard.session.get('formfields', {}).get('fields', {}).keys()]) valid_fields.add('sender_public_name') for match in dollarRE.findall(value): if match not in valid_fields: raise Invalid(_(u'You used an invalid variable substitution.'))
def initialize(self): data = self.getContent() if 'subject' not in data: data['subject'] = utranslate(DOMAIN, _(u'Dear ${recip_honorific} ${recip_first} ${recip_last}'), context=self.request) if 'template' not in data: data['template'] = utranslate(DOMAIN, DEFAULT_LETTER_TEMPLATE, context=self.request) self.wizard.sync()
def _getFieldMap(self, sfobj_type): """ Returns the field mapping that gets set with setFieldMap. """ if sfobj_type == u'Contact': field_source = SF_CONTACT_FIELDMAPPING else: field_source = SF_LEAD_FIELDMAPPING return tuple([dict(field_path=p, form_field=utranslate(DOMAIN, _(l), context=self.request), sf_field=s) for (p, s, l) in field_source])
def fields(self): if not self.optional: return field.Fields() if self.required: title = _(u"You may also choose from the following recipients:") else: title = _(u"You may choose from the following recipients:") fields = field.Fields( schema.Set( __name__ = 'optional-recipients', title = title, description = _(u"(Each person will receive a separate copy of your letter.)"), value_type = schema.Choice( vocabulary = schema.vocabulary.SimpleVocabulary( [schema.vocabulary.SimpleTerm(value, title=title) for value, title in self.optional] ), ), required = False, ) ) fields['optional-recipients'].widgetFactory = CheckBoxFieldWidget return fields
def handleAdd(self, action): data, errors = self.extractData() if errors: self.status = form.AddForm.formErrorsMessage return wizard = self.context.form_instance wizard.update() try: item = wizard.currentStep.add(data) self._finished = True except schema.ValidationError, e: self.status = e else: notify(ObjectCreatedEvent(item)) self.status = _(u'Field added successfully.') class FieldEditForm(PopupForm, form.EditForm): @property def label(self): return _(u"Edit Field: ${field}", mapping={u'field': self.getContent()['title']}) @lazy_property def wizard(self): wizard = self.context.form_instance wizard.update() return wizard
def finish(self): data = self.session if IAdding.providedBy(self.context): # creating a new letter container = self.context.context id = container.generateUniqueId("form-folder") # this is based on the createObject.py script from plone_scripts container.invokeFactory(id=id, type_name='FormFolder') obj=getattr(container, id, None) obj.portal_type = 'Megaphone Action' obj.setTitle(data['general']['title']) # enable preview if the type is letter if data.get('intro', {}).get('megaphone_type', 'letter') == 'letter': submit_label = _(u'Preview') else: submit_label = _(u'Send') obj.setSubmitLabel(utranslate(DOMAIN, submit_label, context=self.request)) # delete the default form fields that come w/ PFG existing_ids = obj.objectIds() deleters = ("mailer", "replyto", "topic", "comments") deleters = [d for d in deleters if d in existing_ids] obj.manage_delObjects(deleters) obj.setActionAdapter(()) if obj._at_rename_after_creation: obj._renameAfterCreation() alsoProvides(obj, IMegaphone) if not obj.getRawAfterValidationOverride(): obj.setAfterValidationOverride('here/@@recipient_multiplexer') obj['thank-you'].setShowAll(0) self.request.response.redirect("%s/@@summary?new=1" % (obj.absolute_url())) self.applySteps(obj, initial_finish=True) else: # existing letter obj = self.context self.request.response.redirect("%s/@@summary" % (obj.absolute_url())) self.applySteps(obj, initial_finish=False) # make sure the saved data adapter is configured properly existing_ids = obj.objectIds() if SAVEDATA_ID not in existing_ids: obj.invokeFactory(id=SAVEDATA_ID, type_name="FormSaveDataAdapter") sda = getattr(obj, SAVEDATA_ID) alsoProvides(sda, IMultiplexedActionAdapter) sda.setTitle(utranslate(DOMAIN, _(u'Saved Signatures'), context=self.request)) sda = getattr(obj, SAVEDATA_ID) adapters = list(obj.actionAdapter) if SAVEDATA_ID in adapters: adapters.remove(SAVEDATA_ID) obj.setActionAdapter(adapters) execCondition = sda.getRawExecCondition() if not execCondition or execCondition in ('python:True', 'python:False'): sda.setExecCondition('python:True') if RENDERED_LETTER_ID not in existing_ids: obj.invokeFactory(id=RENDERED_LETTER_ID, type_name='FormStringField') f = getattr(obj, RENDERED_LETTER_ID) f.setServerSide(True) f.setTitle(utranslate(DOMAIN, _(u'Rendered Letter'), context=self.request)) f.setDescription(utranslate(DOMAIN, _(u'This hidden field is used to provide the rendered letter to the mailer and save data adapters.'), context=self.request)) obj.reindexObject() if IAdding.providedBy(self.context): notify(ObjectInitializedEvent(obj)) else: notify(ObjectEditedEvent(obj))
from Products.PloneFormGen.content.form import FormFolder from z3c.form import field from zope.component.factory import Factory from zope.event import notify from zope.interface import alsoProvides, Interface from zope import schema from zope.annotation.interfaces import IAnnotations from collective.megaphone.config import ANNOTATION_KEY, SAVEDATA_ID, RENDERED_LETTER_ID from persistent.dict import PersistentDict from Products.Archetypes.event import ObjectInitializedEvent, ObjectEditedEvent from Products.CMFPlone.i18nl10n import utranslate MegaphoneActionFactory = Factory( FormFolder, title=_(u'Create a new Megaphone Action') ) class IMegaphoneType(Interface): megaphone_type = schema.Choice( title = _(u'Megaphone Action Type'), description = _(u'You may create a letter or a petition. The type of action you choose ' u'will determine what additional options are available.'), values = ('letter', 'petition'), default = 'letter', ) class IntroStep(wizard.Step): index = ViewPageTemplateFile('intro.pt')
<body> <p tal:content="here/getBody_pre | nothing" /> <p tal:replace="structure here/aq_parent/@@letter-renderer/render_letter" /> <p tal:content="here/getBody_post | nothing" /> <pre tal:content="here/getBody_footer | nothing" /> </body> </html> """ DEFAULT_LETTER_TEMPLATE = \ _('megaphone_default_letter_template', default=u"""Dear ${recip_honorific} ${recip_first} ${recip_last}, ${sender_body} Sincerely, ${sender_first} ${sender_last} ${sender_street} ${sender_city}, ${sender_state} ${sender_zip} ${sender_email} """) THANKYOU_MAILTEMPLATE_BODY = \ """<html xmlns="http://www.w3.org/1999/xhtml"> <head><title></title></head> <body> <p tal:content="here/getBody_pre | nothing" /> <p tal:replace="structure here/aq_parent/@@letter-renderer/render_thankyou" /> <p tal:content="here/getBody_post | nothing" /> <pre tal:content="here/getBody_footer | nothing" />
def render(self): if self._finished: # close popup return _(u'Form submitted successfully.') return super(PopupForm, self).render()
def handleAdd(self, action): data, errors = self.extractData() if errors: self.status = form.AddForm.formErrorsMessage return wizard = self.context.form_instance wizard.update() try: item = wizard.currentStep.add(data) self._finished = True except schema.ValidationError, e: self.status = e else: notify(ObjectCreatedEvent(item)) self.status = _(u'Recipient added successfully.') class RecipientSourceEditForm(PopupForm, form.EditForm): @lazy_property def wizard(self): wizard = self.context.form_instance wizard.update() return wizard def getContent(self): recipients = self.wizard.currentStep._get_recipients() recipient_id = self.request.form.get('form.widgets.recipient_id') if recipient_id is None: raise ValueError('No recipient_id found in request.')
def _get_fields(self): data = self.getContent() if 'fields' in data: return data['fields'] # initialize fields fields = { 'body': { 'field_type': 'text', 'title': utranslate(DOMAIN, _(u'Letter Body'), context=self.request), 'description': utranslate(DOMAIN, _(u'A salutation and signature will be added automatically.'), context=self.request), 'default': utranslate(DOMAIN, _(u'Enter the body of your letter here. A salutation and signature will be added automatically.'), context=self.request), 'required': True, 'order': 0, }, 'sincerely': { 'field_type': 'label', 'title': utranslate(DOMAIN, _(u'Sincerely,'), context=self.request), 'description': u'', 'required': False, 'order': 1, }, 'first': { 'title': utranslate(DOMAIN, _(u'First Name'), context=self.request), 'description': utranslate(DOMAIN, _(u''), context=self.request), 'required': True, 'order': 2, }, 'last': { 'title': utranslate(DOMAIN, _(u'Last Name'), context=self.request), 'description': utranslate(DOMAIN, _(u''), context=self.request), 'required': True, 'order': 3, }, 'email': { 'title': utranslate(DOMAIN, _(u'E-mail Address'), context=self.request), 'description': utranslate(DOMAIN, _(u''), context=self.request), 'required': True, 'validator': 'isEmail', 'order': 4, }, 'street': { 'title': utranslate(DOMAIN, _(u'Street Address'), context=self.request), 'description': utranslate(DOMAIN, _(u''), context=self.request), 'required': False, 'order': 5, }, 'city': { 'title': utranslate(DOMAIN, _(u'City'), context=self.request), 'description': utranslate(DOMAIN, _(u''), context=self.request), 'required': False, 'order': 6, }, 'state': { 'field_type': 'selection', 'title': utranslate(DOMAIN, _(u'State'), context=self.request), 'description': utranslate(DOMAIN, _(u''), context=self.request), 'required': False, 'vocab': STATES, 'order': 7, }, 'zip': { 'title': utranslate(DOMAIN, _(u'Postal Code'), context=self.request), 'description': utranslate(DOMAIN, _(u''), context=self.request), 'required': False, 'validator': 'isZipCode', 'order': 8, 'size': 10, }, } if HAS_CAPTCHA: fields['captcha'] = { 'field_type': 'captcha', 'title': utranslate(DOMAIN, _(u'Please enter this text.'), context=self.request), 'description': utranslate(DOMAIN, _(u'This helps prevent spammers from using this form.'), context=self.request), 'required': True, 'order': 9, } if 'intro' in self.wizard.session.keys() and self.wizard.session['intro']['megaphone_type'] == 'petition': del fields['sincerely'] fields['body']['title'] = utranslate(DOMAIN, _(u'Additional Comment'), context=self.request) fields['body']['description'] = u'' fields['body']['default'] = u'' return self.getContent().setdefault('fields', fields)
def label(self): return _(u"Edit Field: ${field}", mapping={u'field': self.getContent()['title']})
def label(self): return _(u"Add Field: ${field_type}", mapping={u'field_type': self.field_type.token})
def apply(self, pfg, initial_finish=True): data = self.getContent() existing_ids = pfg.objectIds() sfobj_type = data['sfobj_type'] obj_adapter_title = u'Salesforce.com %s Adapter' % sfobj_type lead_source = data['lead_source'] or u'Web' if salesforce_is_configured() and data['save_lead']: if ORG_FIELD_ID not in existing_ids: pfg.invokeFactory(id=ORG_FIELD_ID, type_name='FormStringField') f = getattr(pfg, ORG_FIELD_ID) f.setTitle(utranslate(DOMAIN, _(u'Organization'), context=self.request)) f.setDescription(utranslate(DOMAIN, _(u"This field is used internally to provide the required 'Company' value to Salesforce.com"), context=self.request)) f.setServerSide(True) if not f.getFgDefault(): f.setFgDefault(utranslate(DOMAIN, _(u'[not provided]'), context=self.request)) f.reindexObject() if SF_LEAD_ID not in existing_ids: pfg.invokeFactory(id=SF_LEAD_ID, type_name='SalesforcePFGAdapter') a = getattr(pfg, SF_LEAD_ID) new_adapter = True else: a = getattr(pfg, SF_LEAD_ID) new_adapter = False if new_adapter or not a.getSFObjectType() == sfobj_type: a.setTitle(utranslate(DOMAIN, _(obj_adapter_title), context=self.request)) a.setSFObjectType(sfobj_type) a.setFieldMap(self._getFieldMap(sfobj_type)) a.reindexObject() if hasattr(a, 'setPresetValueMap'): # BBB for salesforcepfgadapter < 1.6b2 preset_map = list(a.getPresetValueMap()) found = False for entry in preset_map: if entry['sf_field'] == 'LeadSource': entry['value'] = lead_source found = True if not found: preset_map.append({'value': lead_source, 'sf_field': 'LeadSource'}) a.setPresetValueMap(tuple(preset_map)) if data['campaign_id']: if CAMPAIGN_ID_FIELD_ID not in existing_ids: pfg.invokeFactory(id=CAMPAIGN_ID_FIELD_ID, type_name='FormStringField') f = getattr(pfg, CAMPAIGN_ID_FIELD_ID) f.setTitle(utranslate(DOMAIN, _(u'Salesforce.com Campaign ID'), context=self.request)) f.setDescription(utranslate(DOMAIN, _(u'This field is used to supply the ID of a Salesforce.com Campaign to the CampaignMember adapter.'), context=self.request)) f.setServerSide(True) f.reindexObject() else: f = getattr(pfg, CAMPAIGN_ID_FIELD_ID) f.setFgDefault(data['campaign_id']) if SF_CAMPAIGNMEMBER_ID not in existing_ids: pfg.invokeFactory(id=SF_CAMPAIGNMEMBER_ID, type_name='SalesforcePFGAdapter') a = getattr(pfg, SF_CAMPAIGNMEMBER_ID) a.setTitle(utranslate(DOMAIN, _(u'Salesforce.com CampaignMember Adapter'), context=self.request)) a.setSFObjectType('CampaignMember') a.setFieldMap(( dict(field_path=CAMPAIGN_ID_FIELD_ID, form_field=utranslate(DOMAIN, _(u'Campaign ID'), context=self.request), sf_field='CampaignId'), )) a.reindexObject() else: a = getattr(pfg, SF_CAMPAIGNMEMBER_ID) a.setDependencyMap(( dict(adapter_id=SF_LEAD_ID, adapter_name=utranslate(DOMAIN, _(obj_adapter_title), context=self.request), sf_field='%sId' % sfobj_type), )) else: objs_to_delete = [] if SF_CAMPAIGNMEMBER_ID in existing_ids: objs_to_delete.append(SF_CAMPAIGNMEMBER_ID) if CAMPAIGN_ID_FIELD_ID in existing_ids: objs_to_delete.append(CAMPAIGN_ID_FIELD_ID) pfg.manage_delObjects(objs_to_delete) if data['campaign_status']: a = getattr(pfg, SF_CAMPAIGNMEMBER_ID, None) if a is not None: preset_map = list(a.getPresetValueMap()) found = False for entry in preset_map: if entry['sf_field'] == 'Status': entry['value'] = data['campaign_status'] found = True if not found: preset_map.append({'value': data['campaign_status'], 'sf_field': 'Status'}) a.setPresetValueMap(tuple(preset_map)) else: a = getattr(pfg, SF_CAMPAIGNMEMBER_ID, None) if a is not None: preset_map = a.getPresetValueMap() preset_map = [entry for entry in preset_map if entry['sf_field'] != 'Status'] a.setPresetValueMap(tuple(preset_map)) else: objs_to_delete = [] if SF_LEAD_ID in existing_ids: objs_to_delete.append(SF_LEAD_ID) if SF_CAMPAIGNMEMBER_ID in existing_ids: objs_to_delete.append(SF_CAMPAIGNMEMBER_ID) if CAMPAIGN_ID_FIELD_ID in existing_ids: objs_to_delete.append(CAMPAIGN_ID_FIELD_ID) if objs_to_delete: pfg.manage_delObjects(objs_to_delete) adapters = list(pfg.actionAdapter) for id in objs_to_delete: if id in adapters: adapters.remove(id) pfg.actionAdapter = adapters