def _getIPloneFormGenFieldsPathTitlePair(self):
        formFolder = aq_parent(self)
        formFolderPath = formFolder.getPhysicalPath()
        formFieldTitles = []

        for formField in formFolder.objectIds():
            fieldObj = getattr(formFolder, formField)
            title = fieldObj.Title().strip()
            path = ",".join(fieldObj.getPhysicalPath()[len(formFolderPath):])
            if IPloneFormGenField.providedBy(fieldObj):
                formFieldTitles.append((title, path))
            # also allow mapping the filename and mimetype for file uploads
            if isinstance(fieldObj, FGFileField):
                formFieldTitles.append((title + ' Filename', path + ',filename'))
                formFieldTitles.append((title + ' Mimetype', path + ',mimetype'))

            # can we also inspect further down the chain
            if fieldObj.isPrincipiaFolderish:
                # since nested folders only go 1 level deep
                # a non-recursive approach approach will work here
                for subFormField in fieldObj.objectIds():
                    subFieldObj = getattr(fieldObj, subFormField)
                    if IPloneFormGenField.providedBy(subFieldObj):
                        # we append a list in this case
                        formFieldTitles.append(("%s --> %s" % (fieldObj.Title().strip(),
                                                               subFieldObj.Title().strip()),
                                                ",".join(subFieldObj.getPhysicalPath()[len(formFolderPath):])))

        return formFieldTitles
예제 #2
0
    def _getIPloneFormGenFieldsPathTitlePair(self):
        formFolder = aq_parent(self)
        formFolderPath = formFolder.getPhysicalPath()
        formFieldTitles = []

        for formField in formFolder.objectIds():
            fieldObj = getattr(formFolder, formField)
            title = fieldObj.Title().strip()
            path = ",".join(fieldObj.getPhysicalPath()[len(formFolderPath):])
            if IPloneFormGenField.providedBy(fieldObj):
                formFieldTitles.append((title, path))
            # also allow mapping the filename and mimetype for file uploads
            if isinstance(fieldObj, FGFileField):
                formFieldTitles.append(
                    (title + ' Filename', path + ',filename'))
                formFieldTitles.append(
                    (title + ' Mimetype', path + ',mimetype'))

            # can we also inspect further down the chain
            if fieldObj.isPrincipiaFolderish:
                # since nested folders only go 1 level deep
                # a non-recursive approach approach will work here
                for subFormField in fieldObj.objectIds():
                    subFieldObj = getattr(fieldObj, subFormField)
                    if IPloneFormGenField.providedBy(subFieldObj):
                        # we append a list in this case
                        formFieldTitles.append(
                            ("%s --> %s" % (fieldObj.Title().strip(),
                                            subFieldObj.Title().strip()),
                             ",".join(subFieldObj.getPhysicalPath()
                                      [len(formFolderPath):])))

        return formFieldTitles
예제 #3
0
 def testDataGridFieldStaticFormFieldVocabsContainsAllPFGFormFields(self):
     """Our SalesforcePFGAdapter depends on the DataGridField which among other 
       options allows for a Fixed Column that can be prepopulated using the fixed_rows
       attribute on the schema field.
     """
     # create an adapter
     self.ff1.invokeFactory('SalesforcePFGAdapter', 'salesforce')
     
     for formField in self.ff1.objectIds():
        fieldObj = getattr(self.ff1, formField)
        fixedRowFields = self.ff1.salesforce.generateFormFieldRows()
        static_titles_for_mapping = [mapping.initialData['form_field'] for mapping in fixedRowFields]
        if IPloneFormGenField.providedBy(fieldObj):
            self.failUnless(fieldObj.Title() in static_titles_for_mapping,
                "Field %s is not listed as a possible field in the computed widget expression \
                method." % fieldObj.Title())
     
     # let's add a new field to our form and immediately make sure it's 
     # available as a row in our FixedRow form fields for the mapping
     self.ff1.invokeFactory('FormTextField', 'formtextfield')
     self.ff1.formtextfield.setTitle('My Form Text Field')
     fixedRowFields = self.ff1.salesforce.generateFormFieldRows()
     static_titles_for_mapping = [mapping.initialData['form_field'] for mapping in fixedRowFields]
     self.failUnless('My Form Text Field' in static_titles_for_mapping,
         "Field formtextfield is not listed as a possible field in the computed widget expression method.")
예제 #4
0
 def testDataGridFieldStaticFormFieldVocabsContainsAllPFGFormFields(self):
     """Our SalesforcePFGAdapter depends on the DataGridField which among other 
       options allows for a Fixed Column that can be prepopulated using the fixed_rows
       attribute on the schema field.
     """
     # create an adapter
     self.ff1.invokeFactory('SalesforcePFGAdapter', 'salesforce')
     
     for formField in self.ff1.objectIds():
         fieldObj = getattr(self.ff1, formField)
         fixedRowFields = self.ff1.salesforce.generateFormFieldRows()
         static_titles_for_mapping = [(mapping.initialData['form_field'], mapping.initialData['field_path']) \
             for mapping in fixedRowFields]
         if IPloneFormGenField.providedBy(fieldObj):
             self.failUnless((fieldObj.Title(), fieldObj.getId()) in static_titles_for_mapping,
                 "Field %s is not listed as a possible field in the computed widget expression \
                 method." % fieldObj.Title())
     
     # let's add a new field to our form and immediately make sure it's 
     # available as a row in our FixedRow form fields for the mapping
     self.ff1.invokeFactory('FormTextField', 'formtextfield')
     self.ff1.formtextfield.setTitle('My Form Text Field')
     fixedRowFields = self.ff1.salesforce.generateFormFieldRows()
     static_titles_for_mapping = [(mapping.initialData['form_field'], mapping.initialData['field_path']) \
         for mapping in fixedRowFields]
     self.failUnless(('My Form Text Field', 'formtextfield') in static_titles_for_mapping,
         "Field formtextfield is not listed as a possible field in the computed widget expression method.")
 def listFormFields(self):
     fields = [
         (obj.getId(), obj.title_or_id())
         for obj in self.aq_parent.objectValues()
         if IPloneFormGenField.providedBy(obj)
     ]
     return atapi.DisplayList(fields)
 def listOptionalFormFields(self):
     fields = [
         (obj.getId(), obj.title_or_id())
         for obj in self.aq_parent.objectValues()
         if IPloneFormGenField.providedBy(obj)
     ]
     return atapi.DisplayList([(u"", _(u"Don't save"))] + fields)
예제 #7
0
    def _getIPloneFormGenFieldProviderTitles(self):
        formFolder = aq_parent(self)
        formFieldTitles = []

        for formField in formFolder.objectIds():
            fieldObj = getattr(formFolder, formField)
            if IPloneFormGenField.providedBy(fieldObj):
                formFieldTitles.append(fieldObj.Title().strip())

        return formFieldTitles
예제 #8
0
 def getPFGFields(self):
     form = aq_parent(aq_inner(self))
     if form.portal_type == 'TempFolder':
         form = aq_parent(form)
     values = []
     for field in form.values():
         if (IPloneFormGenField.providedBy(field)
                 and not IStripeField.providedBy(field)):
             values.append((field.getId(), field.Title()))
     return DisplayList(values)
예제 #9
0
 def getPFGFields(self):
     form = aq_parent(aq_inner(self))
     if form.portal_type == 'TempFolder':
         form = aq_parent(form)
     values = []
     for field in form.values():
         if (IPloneFormGenField.providedBy(field)
                 and not IStripeField.providedBy(field)):
             values.append((
                 field.getId(),
                 field.Title()))
     return DisplayList(values)
예제 #10
0
    def apply(self, pfg, initial_finish=True):
        """
        Apply changes to the underlying PloneFormGen form based on the submitted values.
        """
        data = self.getContent()

        existing_fields = [f.getId() for f in pfg.objectValues() if IPloneFormGenField.providedBy(f) and not f.getServerSide()]
        fields = data['fields']
        for field_id, field_attrs in sorted(fields.items(), key=lambda x: x[1]['order']):
            if 'field_type' in field_attrs:
                field_type = field_attrs['field_type']
            else:
                field_type = 'string'

            f_portal_type = field_type_to_portal_type_map.get(field_type, 'FormStringField')
            if field_id not in existing_fields:
                pfg.invokeFactory(id=field_id, type_name=f_portal_type)
            field = getattr(pfg, field_id)
            field.setTitle(field_attrs['title'].encode('utf8'))
            field.setDescription(field_attrs['description'].encode('utf8'))
            field.setRequired(field_attrs.get('required', False))
            if 'default' in field_attrs:
                default = field_attrs['default']
                if isinstance(default, unicode):
                    default = default.encode('utf8')
                field.setFgDefault(default)
            if 'validator' in field_attrs:
                field.setFgStringValidator(field_attrs['validator'])
            if 'vocab' in field_attrs:
                field.setFgVocabulary(field_attrs['vocab'])
            if 'size' in field_attrs:
                field.setFgsize(field_attrs['size'])
            if field_type == 'text':
                field.setValidateNoLinkSpam(True)

        # sync removed fields
        to_delete = []
        for f in existing_fields:
            if f not in fields:
                to_delete.append(f)
        pfg.manage_delObjects(to_delete)

        # adjust order
        if not initial_finish:
            sorted_field_ids = [k for k, v in sorted(fields.items(), key=lambda x: x[1]['order'])]
            pfg.moveObjectsByDelta(sorted_field_ids, -len(sorted_field_ids))
        
        # reindex fields
        for f in pfg.objectValues():
            f.reindexObject()
    def _getIPloneFormGenFieldsPathTitlePair(self):
        formFolder = aq_parent(self)
        formFolderPath = formFolder.getPhysicalPath()
        formFieldTitles = []

        for formField in formFolder.objectIds():
            fieldObj = getattr(formFolder, formField)
            if IPloneFormGenField.providedBy(fieldObj):
                formFieldTitles.append((fieldObj.Title().strip(),
                                        ",".join(fieldObj.getPhysicalPath()[len(formFolderPath):])))

            # can we also inspect further down the chain
            if fieldObj.isPrincipiaFolderish:
                # since nested folders only go 1 level deep
                # a non-recursive approach approach will work here
                for subFormField in fieldObj.objectIds():
                    subFieldObj = getattr(fieldObj, subFormField)
                    if IPloneFormGenField.providedBy(subFieldObj):
                        # we append a list in this case
                        formFieldTitles.append(("%s --> %s" % (fieldObj.Title().strip(),
                                                               subFieldObj.Title().strip()),
                                                ",".join(subFieldObj.getPhysicalPath()[len(formFolderPath):])))

        return formFieldTitles
예제 #12
0
    def load(self, pfg):
        data = self.getContent()
        if IAdding.providedBy(pfg):
            return data

        fields = data.setdefault('fields', {})
        i = 0
        for f in pfg.objectValues():
            if IPloneFormGenField.providedBy(f):
                if f.getServerSide():
                    continue
                fieldinfo = {
                    'field_type': None,
                    'title': safe_unicode(f.Title()),
                    'description': safe_unicode(f.Description()),
                    'required': f.getRequired(),
                    'order': i,
                }
                if hasattr(f, 'getFgDefault'):
                    fieldinfo['default'] = safe_unicode(f.getFgDefault())
                if f.portal_type == 'FormStringField':
                    fieldinfo['field_type'] = 'string'
                    fieldinfo['validator'] = f.getFgStringValidator()
                    if not fieldinfo['validator']:
                        fieldinfo['validator'] = 'vocabulary_none_text'
                    try:
                        fieldinfo['size'] = int(f.getFgsize())
                    except TypeError:
                        fieldinfo['size'] = 30
                if f.portal_type == 'FormTextField':
                    fieldinfo['field_type'] = 'text'
                if f.portal_type == 'FormBooleanField':
                    fieldinfo['field_type'] = 'boolean'
                    # make sure we match one of the vocab terms
                    if fieldinfo['default'] is not True:
                        fieldinfo['default'] = False
                if f.portal_type == 'FormSelectionField':
                    fieldinfo['field_type'] = 'selection'
                    fieldinfo['vocab'] = safe_unicode("\n".join(f.getFgVocabulary()))
                if f.portal_type == 'FormMultiSelectionField':
                    fieldinfo['field_type'] = 'multiselection'
                    fieldinfo['vocab'] = safe_unicode("\n".join(f.getFgVocabulary()))
                if f.portal_type == 'FormCaptchaField':
                    fieldinfo['field_type'] = 'captcha'
                fields[f.getId()] = fieldinfo
                i += 1
예제 #13
0
    def getLogEntry(self):
        ''' Get's a log entry for your action
        '''
        event = self.event
        obj = event.object
        data = {'info': ''}

        # order of those checks is important since some interfaces
        # base off the others
        if IPloneFormGenField.providedBy(obj):
            # if ploneformgen field, use parent object for modified data
            data['field'] = obj.getId()
            obj = aq_parent(obj)

        # the order of those interface checks matters since some interfaces
        # inherit from others
        if IObjectRemovedEvent.providedBy(event):
            # need to keep track of removed events so it doesn't get called
            # more than once for each object
            action = 'removed'
        elif (
            IObjectInitializedEvent.providedBy(event) or
            IObjectCreatedEvent.providedBy(event) or
            IObjectAddedEvent.providedBy(event)
        ):
            action = 'added'
        elif IObjectMovedEvent.providedBy(event):
            # moves can also be renames. Check the parent object
            if event.oldParent == event.newParent:
                if 'Rename' not in self.rule.rule.title:
                    # cut out here, double action for this event
                    return {}
                data['info'] = 'previous id: %s' % event.oldName
                action = 'rename'
            else:
                if 'Moved' not in self.rule.rule.title:
                    # step out immediately since this could be a double action
                    return {}
                data['info'] = 'previous location: %s/%s' % (
                    '/'.join(event.oldParent.getPhysicalPath()),
                    event.oldName,
                )
                action = 'moved'
        elif IObjectModifiedEvent.providedBy(event):
            action = 'modified'
        elif IActionSucceededEvent.providedBy(event):
            data['info'] = 'workflow transition: %s; comments: %s' % (
                event.action,
                self.get_history_comment(),
            )
            action = 'workflow'
        elif IObjectClonedEvent.providedBy(event):
            action = 'copied'
        elif ICheckinEvent.providedBy(event):
            data['info'] = event.message
            action = 'checked in'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IBeforeCheckoutEvent.providedBy(event):
            action = 'checked out'
            self.request.environ['disable.auditlog'] = True
        elif ICancelCheckoutEvent.providedBy(event):
            action = 'cancel check out'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        else:
            logger.warn('no action matched')
            return {}

        if IWorkingCopy.providedBy(obj):
            # if working copy, iterate, check if Track Working Copies is
            # enabled
            if not self.trackWorkingCopies:
                # if not enabled, we only care about checked messages
                if 'check' not in action:
                    return {}
            # if enabled in control panel, use original object and move
            # working copy path to working_copy
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            relationships = obj.getReferences(
                WorkingCopyRelation.relationship)
            # check relationships, if none, something is wrong, not logging
            # action
            if len(relationships) <= 0:
                return {}
            obj = relationships[0]

        data.update(self._getObjectInfo(obj))
        data['action'] = action
        return data
예제 #14
0
 def listOptionalFormFields(self):
     fields = [(obj.getId(), obj.title_or_id())
               for obj in self.aq_parent.objectValues()
               if IPloneFormGenField.providedBy(obj)]
     return atapi.DisplayList([(u'', _(u"Don't save"))] + fields)
예제 #15
0
    def getLogEntry(self):
        ''' Get's a log entry for your action
        '''
        event = self.event
        obj = event.object
        data = {'info': ''}

        # order of those checks is important since some interfaces
        # base off the others
        if IPloneFormGenField.providedBy(obj):
            # if ploneformgen field, use parent object for modified data
            data['field'] = obj.getId()
            obj = aq_parent(obj)

        # the order of those interface checks matters since some interfaces
        # inherit from others
        if IObjectRemovedEvent.providedBy(event):
            # need to keep track of removed events so it doesn't get called
            # more than once for each object
            action = 'removed'
        elif (IObjectInitializedEvent.providedBy(event)
              or IObjectCreatedEvent.providedBy(event)
              or IObjectAddedEvent.providedBy(event)):
            action = 'added'
        elif IObjectMovedEvent.providedBy(event):
            # moves can also be renames. Check the parent object
            if event.oldParent == event.newParent:
                if 'Rename' not in self.rule.rule.title:
                    # cut out here, double action for this event
                    return {}
                data['info'] = 'previous id: %s' % event.oldName
                action = 'rename'
            else:
                if 'Moved' not in self.rule.rule.title:
                    # step out immediately since this could be a double action
                    return {}
                data['info'] = 'previous location: %s/%s' % (
                    '/'.join(event.oldParent.getPhysicalPath()),
                    event.oldName,
                )
                action = 'moved'
        elif IObjectModifiedEvent.providedBy(event):
            action = 'modified'
        elif IActionSucceededEvent.providedBy(event):
            data['info'] = 'workflow transition: %s; comments: %s' % (
                event.action,
                self.get_history_comment(),
            )
            action = 'workflow'
        elif IObjectClonedEvent.providedBy(event):
            action = 'copied'
        elif ICheckinEvent.providedBy(event):
            data['info'] = event.message
            action = 'checked in'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IBeforeCheckoutEvent.providedBy(event):
            action = 'checked out'
            self.request.environ['disable.auditlog'] = True
        elif ICancelCheckoutEvent.providedBy(event):
            action = 'cancel check out'
            self.request.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        else:
            logger.warn('no action matched')
            return {}

        if IWorkingCopy.providedBy(obj):
            # if working copy, iterate, check if Track Working Copies is
            # enabled
            if not self.trackWorkingCopies:
                # if not enabled, we only care about checked messages
                if 'check' not in action:
                    return {}
            # if enabled in control panel, use original object and move
            # working copy path to working_copy
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            relationships = obj.getReferences(WorkingCopyRelation.relationship)
            # check relationships, if none, something is wrong, not logging
            # action
            if len(relationships) <= 0:
                return {}
            obj = relationships[0]

        data.update(self._getObjectInfo(obj))
        data['action'] = action
        return data
예제 #16
0
 def listFormFields(self):
     fields = [(obj.getId(), obj.title_or_id())
               for obj in self.aq_parent.objectValues()
               if IPloneFormGenField.providedBy(obj)]
     return atapi.DisplayList(fields)
예제 #17
0
    def __call__(self):
        req = getRequest()
        if req.environ.get('disable.auditlog', False):
            return True

        event = self.event
        obj = event.object
        # order of those checks is important since some interfaces
        # base off the others
        rule = inspect.stack()[1][0].f_locals.get('self', None)
        registry = getUtility(IRegistry)
        trackWorkingCopies = registry['collective.auditlog.interfaces.IAuditLogSettings.trackworkingcopies']  # noqa

        if not self.canExecute(rule, req):
            return True  # cut out early, we can't do this event

        data = {
            'info': ''
        }

        if IPloneFormGenField.providedBy(obj):
            # if ploneformgen field, use parent object for modified data
            data['field'] = obj.getId()
            obj = aq_parent(obj)

        # the order of those interface checks matters since some interfaces
        # inherit from others
        if IObjectRemovedEvent.providedBy(event):
            # need to keep track of removed events so it doesn't get called
            # more than once for each object
            action = 'removed'
        elif (IObjectInitializedEvent.providedBy(event) or
                IObjectCreatedEvent.providedBy(event) or
                IObjectAddedEvent.providedBy(event)):
            action = 'added'
        elif IObjectMovedEvent.providedBy(event):
            # moves can also be renames. Check the parent object
            if event.oldParent == event.newParent:
                if rule is None or 'Rename' in rule.rule.title:
                    info = {'previous_id': event.oldName}
                    data['info'] = json.dumps(info)
                    action = 'rename'
                else:
                    # cut out here, double action for this event
                    return True
            else:
                if rule is None or 'Moved' in rule.rule.title:
                    parent_path = '/'.join(event.oldParent.getPhysicalPath())
                    previous_location = parent_path + '/' + event.oldName
                    info = {'previous_location': previous_location}
                    data['info'] = json.dumps(info)
                    action = 'moved'
                else:
                    # step out immediately since this could be a double action
                    return True
        elif IObjectModifiedEvent.providedBy(event):
            action = 'modified'
        elif IActionSucceededEvent.providedBy(event):
            info = {'transition': event.action,
                    'comments': self.get_history_comment()}
            data['info'] = json.dumps(info)
            action = 'workflow'
        elif IObjectClonedEvent.providedBy(event):
            action = 'copied'
        elif ICheckinEvent.providedBy(event):
            info = {'message': event.message}
            data['info'] = json.dumps(info)
            action = 'checked in'
            req.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IBeforeCheckoutEvent.providedBy(event):
            action = 'checked out'
            req.environ['disable.auditlog'] = True
        elif ICancelCheckoutEvent.providedBy(event):
            action = 'cancel check out'
            req.environ['disable.auditlog'] = True
            data['working_copy'] = '/'.join(obj.getPhysicalPath())
            obj = event.baseline
        elif IUserLoggedInEvent.providedBy(event):
            action = 'logged in'
            info = {'user': event.object.getUserName()}
            data['info'] = json.dumps(info)
        elif IUserLoggedOutEvent.providedBy(event):
            action = 'logged out'
        else:
            logger.warn('no action matched')
            return True

        if IWorkingCopy.providedBy(obj):
            # if working copy, iterate, check if Track Working Copies is
            # enabled
            if trackWorkingCopies:
                # if enabled in control panel, use original object and move
                # working copy path to working_copy
                data['working_copy'] = '/'.join(obj.getPhysicalPath())
                relationships = obj.getReferences(
                    WorkingCopyRelation.relationship)
                # check relationships, if none, something is wrong, not logging
                # action
                if len(relationships) > 0:
                    obj = relationships[0]
                else:
                    return True
            else:
                # if not enabled, we only care about checked messages
                if 'check' not in action:
                    return True

        data.update(getObjectInfo(obj))
        data['action'] = action

        addLogEntry(obj, data)
        return True