def test_inherited_schema_still_has_tagged_value(self):
        """An inherited schema should still have the tagged value information
        inherited from its superclass.
        """

        class IFoo(form.Schema):
            """Class with a searchable field
            """
            searchable('baz')
            baz = schema.TextLine(title=u'baz')

        class IBar(IFoo):
            """Schema class which inherits a field from IFoo.
            """

        self.assertEquals([], mergedTaggedValueList(IFoo, SEARCHABLE_KEY))
        self.assertEquals([], mergedTaggedValueList(IBar, SEARCHABLE_KEY))

        grok_component('IFoo', IFoo)
        grok_component('IBar', IBar)

        self.assertEquals([(Interface, 'baz', 'true')],
                          mergedTaggedValueList(IFoo, SEARCHABLE_KEY))
        self.assertEquals([(Interface, 'baz', 'true')],
                          mergedTaggedValueList(IBar, SEARCHABLE_KEY))
Exemplo n.º 2
0
    def __call__(self, context, query=None):
        results = []
        field_ids = []
        exclude = ['im_handle', 'use_parent_address']
        exclude_behaviors = ['plone.app.content.interfaces.INameFromTitle']
        behaviors = set()
        portal_types = api.portal.get_tool('portal_types')
        contact_portal_types = ['person', 'organization', 'position', 'held_position']  # noqa
        for contact_portal_type in contact_portal_types:
            schema = getUtility(
                IDexterityFTI, name=contact_portal_type).lookupSchema()
            fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY)
            for name, field in getFieldsInOrder(schema):
                if name not in exclude and name not in field_ids:
                    visible_name = u'{0}: {1}'.format(
                        contact_portal_type, field.title)
                    field_ids.append(name)
                    results.append((name, visible_name))

            portal_type = getattr(portal_types, contact_portal_type)
            behaviors.update(set(portal_type.behaviors))
        try:
            # remove duplicates photo
            results.remove(('photo', u'held_position: Photo'))
        except ValueError:
            pass
        for behavior in behaviors:
            if behavior not in exclude_behaviors:
                try:
                    # not able to get fields from IDirectoryContactDetails
                    # with nameToInterface(context, behavior)
                    if behavior == 'cpskin.core.behaviors.directorycontact.IDirectoryContactDetails':  # noqa
                        from cpskin.core.behaviors.directorycontact import (
                            IDirectoryContactDetails)
                        interface = IDirectoryContactDetails
                    else:
                        interface = nameToInterface(context, behavior)
                    fieldsets = mergedTaggedValueList(interface, FIELDSETS_KEY)
                    for name, field in getFieldsInOrder(interface):
                        if name not in exclude and name not in field_ids:
                            if not fieldsets:
                                visible_name = field.title
                            else:
                                fieldset = [
                                    fieldset for fieldset in fieldsets if name in fieldset.fields  # noqa
                                ][0]
                                field_ids.append(name)
                                visible_name = u'{0}: {1}'.format(
                                    fieldset.label, field.title)
                            results.append((name, visible_name))
                except:
                    pass
        items = [
            SimpleTerm(i, i, j)
            for i, j in results if j
        ]
        return SimpleVocabulary(items)
Exemplo n.º 3
0
    def __call__(self, context, query=None):
        results = []
        field_ids = []
        exclude = ['im_handle', 'use_parent_address']
        exclude_behaviors = ['plone.app.content.interfaces.INameFromTitle']
        behaviors = set()
        portal_types = api.portal.get_tool('portal_types')
        contact_portal_types = [
            'person', 'organization', 'position', 'held_position'
        ]  # noqa
        for contact_portal_type in contact_portal_types:
            schema = getUtility(IDexterityFTI,
                                name=contact_portal_type).lookupSchema()
            fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY)
            for name, field in getFieldsInOrder(schema):
                if name not in exclude and name not in field_ids:
                    visible_name = u'{0}: {1}'.format(contact_portal_type,
                                                      field.title)
                    field_ids.append(name)
                    results.append((name, visible_name))

            portal_type = getattr(portal_types, contact_portal_type)
            behaviors.update(set(portal_type.behaviors))
        try:
            # remove duplicates photo
            results.remove(('photo', u'held_position: Photo'))
        except ValueError:
            pass
        for behavior in behaviors:
            if behavior not in exclude_behaviors:
                try:
                    # not able to get fields from IDirectoryContactDetails
                    # with nameToInterface(context, behavior)
                    if behavior == 'cpskin.core.behaviors.directorycontact.IDirectoryContactDetails':  # noqa
                        from cpskin.core.behaviors.directorycontact import (
                            IDirectoryContactDetails)
                        interface = IDirectoryContactDetails
                    else:
                        interface = nameToInterface(context, behavior)
                    fieldsets = mergedTaggedValueList(interface, FIELDSETS_KEY)
                    for name, field in getFieldsInOrder(interface):
                        if name not in exclude and name not in field_ids:
                            if not fieldsets:
                                visible_name = field.title
                            else:
                                fieldset = [
                                    fieldset for fieldset in fieldsets
                                    if name in fieldset.fields  # noqa
                                ][0]
                                field_ids.append(name)
                                visible_name = u'{0}: {1}'.format(
                                    fieldset.label, field.title)
                            results.append((name, visible_name))
                except:
                    pass
        items = [SimpleTerm(i, i, j) for i, j in results if j]
        return SimpleVocabulary(items)
Exemplo n.º 4
0
    def update(self):
        schemas = [self.form.schema]

        if IDexterityContent.providedBy(self.context):
            fti = getUtility(IDexterityFTI, name=self.context.portal_type)
            for name in fti.behaviors:
                behavior = queryUtility(IBehavior, name=name)
                if behavior and behavior.interface.extends(model.Schema):
                    schemas.append(behavior.interface)

        directives = []
        for schema in schemas:
            directives += mergedTaggedValueList(schema, DEPENDENCY_KEY)

        dependencies = {}
        for directive in directives:
            dependencies.setdefault(directive.name, []).append(directive)

        todo = collections.deque([self.form])
        while todo:
            group = todo.pop()
            if hasattr(group, "groups"):
                todo.extendleft(group.groups)
            for (name, field) in group.fields.items():
                depends = dependencies.get(name, None)
                if depends is None:
                    continue
                field.field._dependencies = depends
    def test_schema_directives_store_tagged_values(self):
        """Test, if the schema directive values are stored as tagged
        values.
        """
        class IDummy(form.Schema):
            """Dummy schema class.
            """
            searchable('foo')
            foo = schema.TextLine(title=u'Foo')

        self.assertEquals([], mergedTaggedValueList(IDummy, SEARCHABLE_KEY))

        grok_component('IDummy', IDummy)

        self.assertEquals([(Interface, 'foo', 'true')],
                          mergedTaggedValueList(IDummy, SEARCHABLE_KEY))
Exemplo n.º 6
0
def processFieldMoves(form, schema, prefix=''):
    """Process all field moves stored under ORDER_KEY in the schema tagged
    value. This should be run after all schemata have been processed with
    processFields().
    """

    # (name, 'before'/'after', other name)
    order = mergedTaggedValueList(schema, ORDER_KEY)
    for field_name, direction, relative_to in order:

        # Handle shortcut: leading . means 'in this schema'. May be useful
        # if you want to move a field relative to one in the current
        # schema or (more likely) a base schema of the current schema, without
        # having to repeat the full prefix of this schema.

        if relative_to.startswith('.'):
            relative_to = relative_to[1:]
            if prefix:
                relative_to = expandPrefix(prefix) + relative_to

        try:
            if direction == 'before':
                move(form, field_name, before=relative_to, prefix=prefix)
            elif direction == 'after':
                move(form, field_name, after=relative_to, prefix=prefix)
        except KeyError:
            # The relative_to field doesn't exist
            pass
Exemplo n.º 7
0
def processFieldMoves(form, schema, prefix=''):
    """Process all field moves stored under ORDER_KEY in the schema tagged
    value. This should be run after all schemata have been processed with
    processFields().
    """

    # (name, 'before'/'after', other name)
    order = mergedTaggedValueList(schema, ORDER_KEY)
    for field_name, direction, relative_to in order:

        # Handle shortcut: leading . means 'in this schema'. May be useful
        # if you want to move a field relative to one in the current
        # schema or (more likely) a base schema of the current schema, without
        # having to repeat the full prefix of this schema.

        if relative_to.startswith('.'):
            relative_to = relative_to[1:]
            if prefix:
                relative_to = expandPrefix(prefix) + relative_to

        try:
            if direction == 'before':
                move(form, field_name, before=relative_to, prefix=prefix)
            elif direction == 'after':
                move(form, field_name, after=relative_to, prefix=prefix)
        except KeyError:
            # The relative_to field doesn't exist
            pass
Exemplo n.º 8
0
    def update(self):
        schemas = [self.form.schema]

        if IDexterityContent.providedBy(self.context):
            fti = component.getUtility(
                IDexterityFTI,
                name=self.context.portal_type)
            for name in fti.behaviors:
                behavior = component.queryUtility(IBehavior, name=name)
                if behavior and behavior.interface.extends(Schema):
                    schemas.append(behavior.interface)

        directives = []
        for schema in schemas:
            directives += mergedTaggedValueList(schema, DEPENDENCY_KEY)

        dependencies = {}
        for directive in directives:
            dependencies.setdefault(directive.name, []).append(directive)

        todo=collections.deque([self.form])
        while todo:
            group=todo.pop()
            if hasattr(group, "groups"):
                todo.extendleft(group.groups)
            for (name, field) in group.fields.items():
                depends=dependencies.get(name, None)
                if depends is None:
                    continue
                field.field._dependencies=depends
    def test_schema_directives_store_tagged_values(self):
        """Test, if the schema directive values are stored as tagged
        values.
        """

        class IDummy(form.Schema):
            """Dummy schema class.
            """
            searchable('foo')
            foo = schema.TextLine(title=u'Foo')

        self.assertEquals([], mergedTaggedValueList(IDummy, SEARCHABLE_KEY))

        grok_component('IDummy', IDummy)

        self.assertEquals([(Interface, 'foo', 'true')],
                          mergedTaggedValueList(IDummy, SEARCHABLE_KEY))
Exemplo n.º 10
0
    def test_inherited_schema_still_has_tagged_value(self):
        """An inherited schema should still have the tagged value information
        inherited from its superclass.
        """
        class IFoo(model.Schema):
            """Class with a searchable field
            """
            searchable('baz')
            baz = schema.TextLine(title=u'baz')

        class IBar(IFoo):
            """Schema class which inherits a field from IFoo.
            """

        self.assertEqual([(Interface, 'baz', 'true')],
                         mergedTaggedValueList(IFoo, SEARCHABLE_KEY))
        self.assertEqual([(Interface, 'baz', 'true')],
                         mergedTaggedValueList(IBar, SEARCHABLE_KEY))
Exemplo n.º 11
0
def get_soundfile_field(context):
    assignable = IBehaviorAssignable(context, None)
    if assignable is None:
        return
    for behavior_registration in assignable.enumerateBehaviors():
        schema = behavior_registration.interface
        for tgv in mergedTaggedValueList(schema, SOUNDFILE_KEY):
            if tgv.soundfile:
                return tgv.soundfile
Exemplo n.º 12
0
def get_searchable_fields(iface):
    fieldnames = []

    for flag_iface, fieldname, value in mergedTaggedValueList(
            iface, SEARCHABLE_KEY):
        if flag_iface == iface and value:
            fieldnames.append(fieldname)

    return fieldnames
Exemplo n.º 13
0
def get_soundcloud_accessors(context):
    accessors = []
    assignable = IBehaviorAssignable(context, None)
    if assignable is None:
        return accessors
    for behavior_registration in assignable.enumerateBehaviors():
        schema = behavior_registration.interface
        for tgv in mergedTaggedValueList(schema, SOUNDCLOUD_KEY):
            for accessor in tgv.accessors:
                accessors.append((schema, accessor,))
    return accessors
Exemplo n.º 14
0
def get_multilingual_directives(schemas):
    params = {}
    for schema in schemas:
        if not schema:
            continue
        tagged_values = mergedTaggedValueList(schema, MULTILINGUAL_KEY)
        result = {field_name: value for _, field_name, value in tagged_values}

        for field_name, value in result.items():
            params[field_name] = {}
            params[field_name]["language_independent"] = value
    return params
    def test_inherited_schema_still_has_tagged_value(self):
        """An inherited schema should still have the tagged value information
        inherited from its superclass.
        """
        class IFoo(model.Schema):
            """Class with a searchable field
            """
            languageindependent('baz')
            baz = schema.TextLine(title=u'baz')

        class IBar(IFoo):
            """Schema class which inherits a field from IFoo.
            """

        self.assertEqual([(Interface, 'baz', 'true')],
                         mergedTaggedValueList(IFoo, languageindependent.key))
        self.assertTrue(ILanguageIndependentField.providedBy(IFoo['baz']))

        self.assertEqual([(Interface, 'baz', 'true')],
                         mergedTaggedValueList(IBar, languageindependent.key))
        self.assertTrue(ILanguageIndependentField.providedBy(IBar['baz']))
Exemplo n.º 16
0
    def test_inherited_schema_still_has_tagged_value(self):
        """An inherited schema should still have the tagged value information
        inherited from its superclass.
        """

        class IFoo(model.Schema):
            """Class with a searchable field
            """
            languageindependent('baz')
            baz = schema.TextLine(title=u'baz')

        class IBar(IFoo):
            """Schema class which inherits a field from IFoo.
            """

        self.assertEqual([(Interface, 'baz', 'true')],
                         mergedTaggedValueList(IFoo, languageindependent.key))
        self.assertTrue(ILanguageIndependentField.providedBy(IFoo['baz']))

        self.assertEqual([(Interface, 'baz', 'true')],
                         mergedTaggedValueList(IBar, languageindependent.key))
        self.assertTrue(ILanguageIndependentField.providedBy(IBar['baz']))
    def test_schema_directives_store_tagged_values(self):
        """Test, if the schema directive values are stored as tagged values.
        """
        class IDummy(model.Schema):
            """Dummy schema class.
            """
            languageindependent('foo')
            foo = schema.TextLine(title=u'Foo')

        self.assertEqual([(Interface, 'foo', 'true')],
                         mergedTaggedValueList(IDummy,
                                               languageindependent.key))

        self.assertTrue(ILanguageIndependentField.providedBy(IDummy['foo']))
Exemplo n.º 18
0
    def test_schema_directives_store_tagged_values(self):
        """Test, if the schema directive values are stored as tagged values.
        """

        class IDummy(model.Schema):
            """Dummy schema class.
            """
            languageindependent('foo')
            foo = schema.TextLine(title=u'Foo')

        self.assertEqual([(Interface, 'foo', 'true')],
                         mergedTaggedValueList(IDummy,
                                               languageindependent.key))

        self.assertTrue(ILanguageIndependentField.providedBy(IDummy['foo']))
def getLanguageIndependent(context):
    portal_type = context.portal_type
    fti = getUtility(IDexterityFTI, name=portal_type)

    schemata = getAdditionalSchemata(context=context, portal_type=portal_type)
    schemas = tuple(schemata) + (fti.lookupSchema(), )

    fields = set()
    for schema in schemas:
        entries = mergedTaggedValueList(schema, LANGUAGE_INDEPENDENT_KEY)
        for interface, name, value in entries:
            field = schema[name]
            fields.add(field)

    return fields
Exemplo n.º 20
0
    def update(self):
        fieldsets=mergedTaggedValueList(self.form.schema, FIELDSETS_KEY)
        if not isinstance(self.form.groups, list):
            self.form.groups=list(self.form.groups)
        groups=dict([(group.__name__, (index, group)) for (index,group) in enumerate(self.form.groups)])
        for fieldset in fieldsets:
            layout=getattr(fieldset, "layout", None)
            if layout is None:
                continue
            if fieldset.__name__ not in groups:
                continue
            (index, group)=groups[fieldset.__name__]

            if not IGroup.providedBy(group):
                group=self.form.groups[index]=group(self.context, self.request, self.form)
            group.layout=layout
Exemplo n.º 21
0
def mergedTaggedValuesForIRO(schema, name, iro):
    # BBB: this should be in plone.autoform.utils, and
    # mergedTaggedValuesForForm should use this

    # filter out settings irrelevant to this form
    threeples = [t for t in mergedTaggedValueList(schema, name)
                 if t[0] in iro]

    def by_iro(threeple):
        interface = threeple[0]
        return iro.index(interface)
    threeples.sort(key=by_iro)
    d = {}
    # Now iterate through in the reverse order -- the values assigned last win.
    for _, fieldName, value in reversed(threeples):
        d[fieldName] = value
    return d
def get_searchable_contexts_and_fields(obj):
    """Returns a generator of tuples, which contains a storage object for
    each schema (adapted `obj`) and a list of fields on this schema which
    are searchable.
    """

    for schemata in iterSchemata(obj):
        fields = []
        tagged_values = mergedTaggedValueList(schemata, SEARCHABLE_KEY)
        if not tagged_values:
            continue

        for i, name, v in tagged_values:
            fields.append(schema.getFields(schemata).get(name))

        if fields:
            storage = schemata(obj)
            yield storage, fields
Exemplo n.º 23
0
    def update(self):
        fieldsets = mergedTaggedValueList(self.form.schema, FIELDSETS_KEY)
        if not isinstance(self.form.groups, list):
            self.form.groups = list(self.form.groups)
        groups = dict([(group.__name__, (index, group))
                       for (index, group) in enumerate(self.form.groups)])
        for fieldset in fieldsets:
            layout = getattr(fieldset, "layout", None)
            if layout is None:
                continue
            if fieldset.__name__ not in groups:
                continue
            (index, group) = groups[fieldset.__name__]

            if not IGroup.providedBy(group):
                group = self.form.groups[index] = group(
                    self.context, self.request, self.form)
            group.layout = layout
Exemplo n.º 24
0
    def test_mergedTaggedValueList(self):
        class IBase1(Interface):
            pass

        class IBase2(Interface):
            pass

        class IBase3(Interface):
            pass

        class ISchema(IBase1, IBase2, IBase3):
            pass

        IBase1.setTaggedValue(u"foo", [1, 2])  # more specific than IBase2 and IBase3
        IBase3.setTaggedValue(u"foo", [3, 4])  # least specific of the bases
        ISchema.setTaggedValue(u"foo", [4, 5])  # most specific

        self.assertEqual([3, 4, 1, 2, 4, 5], utils.mergedTaggedValueList(ISchema, u"foo"))
Exemplo n.º 25
0
    def test_mergedTaggedValueList(self):
        class IBase1(Interface):
            pass

        class IBase2(Interface):
            pass

        class IBase3(Interface):
            pass

        class ISchema(IBase1, IBase2, IBase3):
            pass

        IBase1.setTaggedValue(u"foo",
                              [1, 2])  # more specific than IBase2 and IBase3
        IBase3.setTaggedValue(u"foo", [3, 4])  # least specific of the bases
        ISchema.setTaggedValue(u"foo", [4, 5])  # most specific

        self.assertEquals([3, 4, 1, 2, 4, 5],
                          utils.mergedTaggedValueList(ISchema, u"foo"))
Exemplo n.º 26
0
def mergedTaggedValuesForIRO(schema, name, iro):
    """Finds a list of (interface, fieldName, value) 3-ples from the tagged
    value named 'name', on 'schema' and all of its bases.  Returns a dict of
    fieldName => value, where the value is from the tuple for that fieldName
    whose interface is highest in the interface resolution order, among the
    interfaces actually provided by 'form'.
    """
    # filter out settings irrelevant to this form
    threeples = [t for t in mergedTaggedValueList(schema, name)
                 if t[0] in iro]

    # Sort by interface resolution order of the form interface,
    # then by IRO of the interface the value came from
    # (that is the input order, so we can rely on Python's stable sort)
    def by_iro(threeple):
        interface = threeple[0]
        return iro.index(interface)
    threeples.sort(key=by_iro)
    d = {}
    # Now iterate through in the reverse order -- the values assigned last win.
    for _, fieldName, value in reversed(threeples):
        d[fieldName] = value
    return d
Exemplo n.º 27
0
def mergedTaggedValuesForIRO(schema, name, iro):
    """Finds a list of (interface, fieldName, value) 3-ples from the tagged
    value named 'name', on 'schema' and all of its bases.  Returns a dict of
    fieldName => value, where the value is from the tuple for that fieldName
    whose interface is highest in the interface resolution order, among the
    interfaces actually provided by 'form'.
    """
    # filter out settings irrelevant to this form
    threeples = [t for t in mergedTaggedValueList(schema, name) if t[0] in iro]

    # Sort by interface resolution order of the form interface,
    # then by IRO of the interface the value came from
    # (that is the input order, so we can rely on Python's stable sort)
    def by_iro(threeple):
        interface = threeple[0]
        return iro.index(interface)

    threeples.sort(key=by_iro)
    d = {}
    # Now iterate through in the reverse order -- the values assigned last win.
    for _, fieldName, value in reversed(threeples):
        d[fieldName] = value
    return d
Exemplo n.º 28
0
def get_searchable_contexts_and_fields(obj):
    """Returns a generator of tuples, which contains a storage object for
    each schema (adapted `obj`) and a list of fields on this schema which
    are searchable.
    """

    for schemata in iterSchemata(obj):
        fields = []
        tagged_values = mergedTaggedValueList(schemata, SEARCHABLE_KEY)
        if not tagged_values:
            continue

        for _i, name, _v in tagged_values:
            field = schema.getFields(schemata).get(name)
            if not field:
                dottedname = '.'.join((schemata.__module__, schemata.__name__))
                logging.error('%s has no field "%s"', dottedname, name)

            else:
                fields.append(field)

        if fields:
            storage = schemata(obj)
            yield storage, fields
def get_searchable_contexts_and_fields(obj):
    """Returns a generator of tuples, which contains a storage object for
    each schema (adapted `obj`) and a list of fields on this schema which
    are searchable.
    """

    for schemata in iterSchemata(obj):
        fields = []
        tagged_values = mergedTaggedValueList(schemata, SEARCHABLE_KEY)
        if not tagged_values:
            continue

        for _i, name, _v in tagged_values:
            field = schema.getFields(schemata).get(name)
            if not field:
                dottedname = '.'.join((schemata.__module__, schemata.__name__))
                logging.error('%s has no field "%s"', dottedname, name)

            else:
                fields.append(field)

        if fields:
            storage = schemata(obj)
            yield storage, fields
    def test_marking_field_as_searchable(self):
        self.assertEquals([], mergedTaggedValueList(IExample, SEARCHABLE_KEY))

        searchable(IExample, u'foo')
        self.assertEquals([(IExample, 'foo', 'true')],
                          mergedTaggedValueList(IExample, SEARCHABLE_KEY))
Exemplo n.º 31
0
def processFields(form, schema, prefix='', defaultGroup=None,
                  permissionChecks=True):
    """Add the fields from the schema to the form, taking into account
    the hints in the various tagged values as well as fieldsets. If prefix
    is given, the fields will be prefixed with this prefix. If
    defaultGroup is given (as a Fieldset instance), any field not explicitly
    placed into a particular fieldset, will be added to the given group,
    which must exist already. If permissionChecks is false,
    permission checks are ignored.
    """

    # Get data from tagged values, flattening data from super-interfaces

    # Note: The names always refer to a field in the schema, and never
    # contain a prefix.

    # { name => True }
    omitted = mergedTaggedValuesForForm(schema, OMITTED_KEY, form)

    # { name => e.g. 'hidden' }
    modes = mergedTaggedValuesForForm(schema, MODES_KEY, form)

    # { name => widget/dotted name }
    widgets = mergedTaggedValueDict(schema, WIDGETS_KEY)

    # list of IFieldset instances
    fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY)

    # Get either read or write permissions depending on what type of
    # form this is
    readPermissions = {}  # field name -> permission name
    writePermissions = {}  # field name -> permission name
    permissionCache = {}  # permission name -> allowed/disallowed

    if permissionChecks:
        # name => permission name
        readPermissions = mergedTaggedValueDict(
            schema,
            READ_PERMISSIONS_KEY
        )
        # name => permission name
        writePermissions = mergedTaggedValueDict(
            schema,
            WRITE_PERMISSIONS_KEY
        )
        securityManager = getSecurityManager()

    # Find the fields we should not worry about

    groups = {}
    doNotProcess = list(form.fields.keys())

    for fieldName, status in omitted.items():
        if status and status != 'false':
            doNotProcess.append(_fn(prefix, fieldName))

    for group in form.groups:
        doNotProcess.extend(list(group.fields.keys()))

        groupName = getattr(group, '__name__', group.label)
        groups[groupName] = group

    # Find all allowed fields so that we have something to select from
    omitReadOnly = form.mode != DISPLAY_MODE
    allFields = field.Fields(
        schema,
        prefix=prefix,
        omitReadOnly=omitReadOnly
    ).omit(*doNotProcess)

    # Check permissions
    if permissionChecks:

        disallowedFields = []

        for fieldName, fieldInstance in allFields.items():
            fieldName = fieldInstance.__name__
            fieldMode = fieldInstance.mode or form.mode

            permissionName = None
            if fieldMode == DISPLAY_MODE:
                permissionName = readPermissions.get(_bn(fieldInstance), None)
            elif fieldMode == INPUT_MODE:
                permissionName = writePermissions.get(_bn(fieldInstance), None)
            if permissionName is not None:
                if permissionName not in permissionCache:
                    permission = queryUtility(IPermission, name=permissionName)
                    if permission is None:
                        permissionCache[permissionName] = True
                    else:
                        permissionCache[permissionName] = bool(
                            securityManager.checkPermission(
                                permission.title,
                                form.context
                            )
                        )
                if not permissionCache.get(permissionName, True):
                    disallowedFields.append(fieldName)

        allFields = allFields.omit(*disallowedFields)

    # Keep track of which fields are in a fieldset, and, by elimination,
    # which ones are not

    fieldsetFields = []
    for fieldset in fieldsets:
        for fieldName in fieldset.fields:
            fieldsetFields.append(_fn(prefix, fieldName))

    # Set up the default fields, widget factories and widget modes

    newFields = allFields.omit(*fieldsetFields)
    _processWidgets(form, widgets, modes, newFields)

    if not defaultGroup:
        form.fields += newFields
    else:
        groups[defaultGroup].fields += newFields

    # Set up fields for fieldsets

    for fieldset in fieldsets:

        newFields = allFields.select(*[_fn(prefix, fieldName)
                                       for fieldName in fieldset.fields
                                       if _fn(prefix, fieldName) in allFields])

        if getattr(form, 'showEmptyGroups', False) or (len(newFields) > 0):
            _processWidgets(form, widgets, modes, newFields)

            if fieldset.__name__ not in groups:
                group = GroupFactory(fieldset.__name__,
                                     label=fieldset.label,
                                     description=fieldset.description,
                                     fields=newFields)
                form.groups.append(group)
                groups[group.__name__] = group
            else:
                groups[fieldset.__name__].fields += newFields
    def test_marking_field_as_searchable(self):
        self.assertEquals([], mergedTaggedValueList(IExample, SEARCHABLE_KEY))

        searchable(IExample, u'foo')
        self.assertEquals([(IExample, 'foo', 'true')],
                          mergedTaggedValueList(IExample, SEARCHABLE_KEY))
Exemplo n.º 33
0
    def updateFieldsFromSchemata(self):

        # If the form is called from the ++widget++ traversal namespace,
        # we won't have a user yet. In this case, we can't perform permission
        # checks.

        have_user = bool(self.request.get('AUTHENTICATED_USER', False))

        # Turn fields into an instance variable, since we will be modifying it
        self.fields = field.Fields(self.fields)

        # Copy groups to an instance variable and ensure that we have
        # the more mutable factories, rather than 'Group' subclasses

        groups = []

        for group in self.groups:
            group_name = getattr(group, '__name__', group.label)
            fieldset_group = GroupFactory(
                group_name,
                field.Fields(group.fields),
                group.label,
                getattr(group, 'description', None)
            )
            groups.append(fieldset_group)

        # Copy to instance variable only after we have potentially read from
        # the class
        self.groups = groups

        prefixes = {}

        if self.schema is not None:
            processFields(self, self.schema, permissionChecks=have_user)

        # Set up all widgets, modes, omitted fields and fieldsets
        for schema in self.additionalSchemata:

            # Find the prefix to use for this form and cache for next round
            prefix = self.getPrefix(schema)
            if prefix and prefix in prefixes:
                prefix = schema.__identifier__
            prefixes[schema] = prefix

            # By default, there's no default group, i.e. fields go
            # straight into the default fieldset

            defaultGroup = None

            # Create groups from schemata if requested and set default
            # group

            if self.autoGroups:
                # use interface name, or prefix for anonymous schema
                group_name = schema.__name__ or prefix or None

                # Look for group - note that previous processFields
                # may have changed the groups list, so we can't easily
                # store this in a dict.
                found = False
                for g in self.groups:
                    if group_name == getattr(g, '__name__', g.label):
                        found = True
                        break

                if not found:
                    fieldset_group = GroupFactory(
                        group_name,
                        field.Fields(),
                        label=group_name,
                        description=schema.__doc__,
                        order=DEFAULT_ORDER,
                    )
                    self.groups.append(fieldset_group)

                defaultGroup = group_name

            processFields(
                self,
                schema,
                prefix=prefix,
                defaultGroup=defaultGroup,
                permissionChecks=have_user
            )

        # Then process relative field movements. The base schema is processed
        # last to allow it to override any movements made in additional
        # schemata.
        rules = None
        for schema in self.additionalSchemata:
            order = mergedTaggedValueList(schema, ORDER_KEY)
            rules = self._calculate_field_moves(
                order,
                prefix=prefixes[schema],
                rules=rules,
            )
        if self.schema is not None:
            order = mergedTaggedValueList(self.schema, ORDER_KEY)
            rules = self._calculate_field_moves(order, rules=rules)
        self._cleanup_rules(rules)
        self._process_field_moves(rules)
        self._process_group_order()
Exemplo n.º 34
0
def _process_fieldsets(form, schema, groups, all_fields, prefix,
                       default_group):
    """ Keep track of which fields are in a fieldset, and, by elimination,
    which ones are not
    """
    # { name => e.g. 'hidden' }
    modes = mergedTaggedValuesForForm(schema, MODES_KEY, form)

    # { name => widget/dotted name }
    widgets = mergedTaggedValueDict(schema, WIDGETS_KEY)

    # list of IFieldset instances
    fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY)

    # process primary schema fieldsets
    fieldset_fields = []
    for fieldset in fieldsets:
        for field_name in fieldset.fields:
            fieldset_fields.append(_process_prefixed_name(prefix, field_name))

    # Set up the default fields, widget factories and widget modes
    new_fields = all_fields.omit(*fieldset_fields)
    _process_widgets(form, widgets, modes, new_fields)

    if not default_group:
        form.fields += new_fields
    else:
        groups[default_group].fields += new_fields

    # Set up fields for fieldsets

    for fieldset in fieldsets:
        new_fields = all_fields.select(*[
            _process_prefixed_name(prefix, name) for name in fieldset.fields
            if _process_prefixed_name(prefix, name) in all_fields
        ])

        if fieldset.__name__ in groups:
            # Process also, if no fields are defined to allow fieldset-only
            # configurations via plone.supermodel fieldset directive.
            group = groups[fieldset.__name__]
            group.fields += new_fields
            if (fieldset.label and group.label != fieldset.label
                    and group.__name__ != fieldset.label  # defaults to name!
                ):
                group.label = fieldset.label
            if (fieldset.description
                    and group.description != fieldset.description):
                group.description = fieldset.description
            if (fieldset.order and fieldset.order != DEFAULT_ORDER
                    and fieldset.order != group.order):
                group.order = fieldset.order

        if len(new_fields) > 0 or getattr(form, 'showEmptyGroups', False):
            _process_widgets(form, widgets, modes, new_fields)
            if fieldset.__name__ not in groups:
                group = GroupFactory(fieldset.__name__,
                                     label=fieldset.label,
                                     description=fieldset.description,
                                     order=fieldset.order,
                                     fields=new_fields)
                form.groups.append(group)
                groups[group.__name__] = group
Exemplo n.º 35
0
def processFields(form, schema, prefix='', defaultGroup=None, permissionChecks=True):
    """Add the fields from the schema to the form, taking into account
    the hints in the various tagged values as well as fieldsets. If prefix
    is given, the fields will be prefixed with this prefix. If 
    defaultGroup is given (as a Fieldset instance), any field not explicitly
    placed into a particular fieldset, will be added to the given group,
    which must exist already. If permissionChecks is false,
    permission checks are ignored.
    """

    # Get data from tagged values, flattening data from super-interfaces
    
    # Note: The names always refer to a field in the schema, and never contain a prefix.
    
    omitted   = mergedTaggedValuesForForm(schema, OMITTED_KEY, form)   # { name => True }
    modes     = mergedTaggedValuesForForm(schema, MODES_KEY, form)     # { name => e.g. 'hidden' }
    widgets   = mergedTaggedValueDict(schema, WIDGETS_KEY)             # { name => widget/dotted name }
    
    fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY)           # list of IFieldset instances
    
    # Get either read or write permissions depending on what type of form this is
    
    readPermissions  = {}  # field name -> permission name
    writePermissions = {}  # field name -> permission name
    permissionCache  = {}  # permission name -> allowed/disallowed
    
    if permissionChecks:
        readPermissions  = mergedTaggedValueDict(schema, READ_PERMISSIONS_KEY)  # name => permission name
        writePermissions = mergedTaggedValueDict(schema, WRITE_PERMISSIONS_KEY) # name => permission name
        securityManager  = getSecurityManager()
        
    # Find the fields we should not worry about
    
    groups = {}
    doNotProcess = list(form.fields.keys())

    for fieldName, status in omitted.items():
        if status and status != 'false':
            doNotProcess.append(_fn(prefix, fieldName))
    
    for group in form.groups:
        doNotProcess.extend(list(group.fields.keys()))
        
        groupName = getattr(group, '__name__', group.label)
        groups[groupName] = group

    # Find all allowed fields so that we have something to select from
    omitReadOnly = form.mode != DISPLAY_MODE
    allFields = field.Fields(schema, prefix=prefix, omitReadOnly=omitReadOnly).omit(*doNotProcess)
    
    # Check permissions
    if permissionChecks:
        
        disallowedFields = []
        
        for fieldName, fieldInstance in allFields.items():
            fieldName = fieldInstance.__name__
            fieldMode = fieldInstance.mode or form.mode
            
            permissionName = None
            if fieldMode == DISPLAY_MODE:
                permissionName = readPermissions.get(_bn(fieldInstance), None)
            elif fieldMode == INPUT_MODE:
                permissionName = writePermissions.get(_bn(fieldInstance), None)
            if permissionName is not None:
                if permissionName not in permissionCache:
                    permission = queryUtility(IPermission, name=permissionName)
                    if permission is None:
                        permissionCache[permissionName] = True
                    else:
                        permissionCache[permissionName] = bool(securityManager.checkPermission(permission.title, form.context))
                if not permissionCache.get(permissionName, True):
                    disallowedFields.append(fieldName)
        
        allFields = allFields.omit(*disallowedFields)
    
    # Keep track of which fields are in a fieldset, and, by elimination,
    # which ones are not 
    
    fieldsetFields = []
    for fieldset in fieldsets:
        for fieldName in fieldset.fields:
            fieldsetFields.append(_fn(prefix, fieldName))
    
    # Set up the default fields, widget factories and widget modes
    
    newFields = allFields.omit(*fieldsetFields)
    _processWidgets(form, widgets, modes, newFields)
    
    if not defaultGroup:
        form.fields += newFields
    else:
        groups[defaultGroup].fields += newFields
    
    # Set up fields for fieldsets
    
    for fieldset in fieldsets:
        
        newFields = allFields.select(*[_fn(prefix, fieldName) 
                                            for fieldName in fieldset.fields
                                                if _fn(prefix, fieldName) in allFields])
        
        if len(newFields) > 0:        
            _processWidgets(form, widgets, modes, newFields)
        
            if fieldset.__name__ not in groups:
                form.groups.append(GroupFactory(fieldset.__name__,
                                                label=fieldset.label,
                                                description=fieldset.description,
                                                fields=newFields))
            else:
                groups[fieldset.__name__].fields += newFields
Exemplo n.º 36
0
def _process_fieldsets(
    form,
    schema,
    groups,
    all_fields,
    prefix,
    default_group
):
    """ Keep track of which fields are in a fieldset, and, by elimination,
    which ones are not
    """
    # { name => e.g. 'hidden' }
    modes = mergedTaggedValuesForForm(schema, MODES_KEY, form)

    # { name => widget/dotted name }
    widgets = mergedTaggedValueDict(schema, WIDGETS_KEY)

    # list of IFieldset instances
    fieldsets = mergedTaggedValueList(schema, FIELDSETS_KEY)

    # process primary schema fieldsets
    fieldset_fields = []
    for fieldset in fieldsets:
        for field_name in fieldset.fields:
            fieldset_fields.append(_process_prefixed_name(prefix, field_name))

    # Set up the default fields, widget factories and widget modes
    new_fields = all_fields.omit(*fieldset_fields)
    _process_widgets(form, widgets, modes, new_fields)

    if not default_group:
        form.fields += new_fields
    else:
        groups[default_group].fields += new_fields

    # Set up fields for fieldsets

    for fieldset in fieldsets:
        new_fields = all_fields.select(
            *[_process_prefixed_name(prefix, name) for name in fieldset.fields
              if _process_prefixed_name(prefix, name) in all_fields]
        )

        if fieldset.__name__ in groups:
            # Process also, if no fields are defined to allow fieldset-only
            # configurations via plone.supermodel fieldset directive.
            group = groups[fieldset.__name__]
            group.fields += new_fields
            if (
                fieldset.label and
                group.label != fieldset.label and
                group.__name__ != fieldset.label  # defaults to name!
            ):
                group.label = fieldset.label
            if (
                fieldset.description and
                group.description != fieldset.description
            ):
                group.description = fieldset.description
            if (
                fieldset.order and
                fieldset.order != DEFAULT_ORDER and
                fieldset.order != group.order
            ):
                group.order = fieldset.order

        if len(new_fields) > 0 or getattr(form, 'showEmptyGroups', False):
            _process_widgets(form, widgets, modes, new_fields)
            if fieldset.__name__ not in groups:
                group = GroupFactory(fieldset.__name__,
                                     label=fieldset.label,
                                     description=fieldset.description,
                                     order=fieldset.order,
                                     fields=new_fields)
                form.groups.append(group)
                groups[group.__name__] = group
Exemplo n.º 37
0
    def updateFieldsFromSchemata(self):

        # If the form is called from the ++widget++ traversal namespace,
        # we won't have a user yet. In this case, we can't perform permission
        # checks.

        have_user = bool(self.request.get('AUTHENTICATED_USER', False))

        # Turn fields into an instance variable, since we will be modifying it
        self.fields = field.Fields(self.fields)

        # Copy groups to an instance variable and ensure that we have
        # the more mutable factories, rather than 'Group' subclasses

        groups = []

        for group in self.groups:
            group_name = getattr(group, '__name__', group.label)
            fieldset_group = GroupFactory(group_name,
                                          field.Fields(group.fields),
                                          group.label,
                                          getattr(group, 'description', None))
            groups.append(fieldset_group)

        # Copy to instance variable only after we have potentially read from
        # the class
        self.groups = groups

        prefixes = {}

        if self.schema is not None:
            processFields(self, self.schema, permissionChecks=have_user)

        # Set up all widgets, modes, omitted fields and fieldsets
        for schema in self.additionalSchemata:

            # Find the prefix to use for this form and cache for next round
            prefix = self.getPrefix(schema)
            if prefix and prefix in prefixes:
                prefix = schema.__identifier__
            prefixes[schema] = prefix

            # By default, there's no default group, i.e. fields go
            # straight into the default fieldset

            defaultGroup = None

            # Create groups from schemata if requested and set default
            # group

            if self.autoGroups:
                # use interface name, or prefix for anonymous schema
                group_name = schema.__name__ or prefix or None

                # Look for group - note that previous processFields
                # may have changed the groups list, so we can't easily
                # store this in a dict.
                found = False
                for g in self.groups:
                    if group_name == getattr(g, '__name__', g.label):
                        found = True
                        break

                if not found:
                    fieldset_group = GroupFactory(
                        group_name,
                        field.Fields(),
                        label=group_name,
                        description=schema.__doc__,
                        order=DEFAULT_ORDER,
                    )
                    self.groups.append(fieldset_group)

                defaultGroup = group_name

            processFields(self,
                          schema,
                          prefix=prefix,
                          defaultGroup=defaultGroup,
                          permissionChecks=have_user)

        # Then process relative field movements. The base schema is processed
        # last to allow it to override any movements made in additional
        # schemata.
        rules = {'__all__': {}}
        for schema in self.additionalSchemata:
            order = mergedTaggedValueList(schema, ORDER_KEY)
            rules = self._calculate_field_moves(
                order,
                prefix=prefixes[schema],
                rules=rules,
            )
        if self.schema is not None:
            order = mergedTaggedValueList(self.schema, ORDER_KEY)
            rules = self._calculate_field_moves(order, rules=rules)
        self._cleanup_rules(rules)
        self._process_field_moves(rules)
        self._process_group_order()