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