Ejemplo n.º 1
0
    def queryCatalog(self, limit):
        """
        """
        querybuilder = QueryBuilder(self, self.request)
        if not hasattr(self.data, 'sort_on'):
            self.data.sort_on = 'effective'
        if not hasattr(self.data, 'sort_order'):
            self.data.sort_order = False
        if not hasattr(self.data, 'sort_folderorder'):
            self.data.sort_folderorder = False

        sort_order = 'descending' if self.data.sort_order else 'ascending'
        sort_on = self.data.sort_on

        if self.data.sort_folderorder:
            sort_on = 'getObjPositionInParent'

        query = list(self.data.query)

        if ICollection.providedBy(self.context):
            query += self.context.query and self.context.query or []
            parent = aq_parent(aq_inner(self.context))
            if ICollection.providedBy(parent):
                query += parent.query and parent.query or []
        return querybuilder(query=query,
                            sort_on=sort_on,
                            sort_order=sort_order,
                            limit=limit)
Ejemplo n.º 2
0
 def get_collection_schema_from_interface_schema(self, schema):
     collection = {}
     for name in schema:
         if IDate.providedBy(schema[name]) or \
                                             IDatetime.providedBy(schema[name]):
             collection['field.'+name] = 'time'
         elif IDecimal.providedBy(schema[name]) or \
                             IFloat.providedBy(schema[name]) or \
                                            IInt.providedBy(schema[name]):
             collection['field.'+name] = 'number'
         elif IBool.providedBy(schema[name]):
             collection['field.'+name] = 'bool'
         elif ICollection.providedBy(schema[name]):
             if not ICollection.providedBy(schema[name].value_type) and not \
                         IDict.providedBy(schema[name].value_type):
                 collection['field.'+name] = 'array'
         elif IDict.providedBy(schema[name]):
             if IText.providedBy(schema[name].key_type) and \
                         IText.providedBy(schema[name].value_type):
                 collection['field.'+name] = 'array'
         # this is a pretty weak check for a IP address field.  We might want
         # to update this to look for a field validator based on the ipaddress package
         # or mark this field with a special interface indicating it is an 
         # IP address
         elif IDottedName.providedBy(schema[name]) and \
                         (schema[name].min_dots == schema[name].max_dots == 3):
             collection['field.'+name] = 'cidr'
         elif IText.providedBy(schema[name]) or \
                                     INativeString.providedBy(schema[name]):
             collection['field.'+name] = 'string'
     return collection
Ejemplo n.º 3
0
 def _handleSave(self, action, msg='Saved form data'):
     self.save_attempt = True
     data, errors = self.extractData()
     if errors or IFormDefinition.providedBy(self.context) or self.saved:
         return False  # just validate if errors, or if context if defn
     if not self.saved:
         result = {}  # submitted data. k: group name; v: dict of name/value
         group_keys = []
         for group in self.groups:
             groupdata = {}
             form_group_data = group.extractData()[0]
             for name, _field in group.fields.items():
                 group_keys.append(name)
                 fieldname = _field.field.__name__
                 default = getattr(_field.field, 'default', None)
                 field_data = form_group_data.get(name, default)
                 if ICollection.providedBy(_field.field):
                     if isinstance(_field.field.value_type, DictRow):
                         is_nonempty_row = lambda v: any(v.values())
                         field_data = filter(is_nonempty_row, field_data)
                 groupdata[fieldname] = field_data
             result[group.__name__] = groupdata
         # filter default fieldset values, ignore group values in data dict:
         result[''] = dict([(k, v) for k, v in data.items()
                            if k not in group_keys])
         self._saveResult(result)
         self.saved = True
         history_log(self.context, message=msg, set_modified=True)
         notify(ObjectModifiedEvent(self.context))
         transaction.get().note(msg)
     self._status.addStatusMessage('Saved form data', type='info')
     return True
Ejemplo n.º 4
0
def valueToElement(field, value, name=None, force=False):
    """Create and return an element that describes the given value, which is
    assumed to be valid for the given field.

    If name is given, this will be used as the new element name. Otherwise,
    the field's __name__ attribute is consulted.

    If force is True, the value will always be written. Otherwise, it is only
    written if it is not equal to field.missing_value.
    """

    if name is None:
        name = field.__name__

    child = etree.Element(name)

    if value is not None and (force or value != field.missing_value):

        if IDict.providedBy(field):
            key_converter = IToUnicode(field.key_type)
            for k, v in value.items():
                list_element = valueToElement(field.value_type, v, 'element', force)
                list_element.attrib['key'] = key_converter.toUnicode(k)
                child.append(list_element)

        elif ICollection.providedBy(field):
            for v in value:
                list_element = valueToElement(field.value_type, v, 'element', force)
                child.append(list_element)

        else:
            converter = IToUnicode(field)
            child.text = converter.toUnicode(value)

    return child
Ejemplo n.º 5
0
 def _handleSave(self, action, msg='Saved form data'):
     self.save_attempt = True
     data, errors = self.extractData()
     if errors or IFormDefinition.providedBy(self.context) or self.saved:
         return False  # just validate if errors, or if context if defn
     if not self.saved:
         result = {}  # submitted data. k: group name; v: dict of name/value
         group_keys = []
         for group in self.groups:
             groupdata = {}
             form_group_data = group.extractData()[0]
             for name, _field in group.fields.items():
                 group_keys.append(name)
                 fieldname = _field.field.__name__
                 default = getattr(_field.field, 'default', None)
                 field_data = form_group_data.get(name, default)
                 if ICollection.providedBy(_field.field):
                     if isinstance(_field.field.value_type, DictRow):
                         is_nonempty_row = lambda v: any(v.values())
                         field_data = filter(is_nonempty_row, field_data)
                 groupdata[fieldname] = field_data
             result[group.__name__] = groupdata
         # filter default fieldset values, ignore group values in data dict:
         result[''] = dict([(k, v) for k, v in data.items()
                            if k not in group_keys])
         self._saveResult(result)
         self.saved = True
         history_log(self.context, message=msg, set_modified=True)
         notify(ObjectModifiedEvent(self.context))
         transaction.get().note(msg)
     self._status.addStatusMessage('Saved form data', type='info')
     return True
Ejemplo n.º 6
0
 def import_node_for_field(self, field, child):
     value = None
     
     # If we have a collection, we need to look at the value_type.
     # We look for <element>value</element> child nodes and get the
     # value from there
     if ICollection.providedBy(field):
         value_type = field.value_type
         value = []
         for element in child.childNodes:
             if element.nodeName != 'element':
                 continue
             value.append(self.import_node_for_field(value_type, element))
     elif IObject.providedBy(field):
         value = {}
         for element in child.childNodes:
             if element.nodeName != 'property':
                 continue
             property_key = self.extract_text(element.attributes['name'])
             property_value = self.import_node_for_field(field.schema[property_key], element)
             value[property_key] = property_value
     elif IChoice.providedBy(field):
         # Choice fields can be optional, so treat an empty contents as None
         value = self.extract_text(child)
         if not value:
             value = None
         else:
             value = self.from_unicode(field, value)
     else:
         # Otherwise, just get the value of the <property /> node
         value = self.extract_text(child)
         if not (field.getName() == 'root' and value in ['', '/']):
             value = self.from_unicode(field, value)
     value = self.field_typecast(field, value)
     return value
 def __getattr__(self, name):
     reg = self.__registry__
     if name not in self.__schema__:
         raise AttributeError(name)
     field = self.__schema__.get(name)
     if IObject.providedBy(field):
         iface = field.schema
         collection = reg.collectionOfInterface(
                         iface,
                         check=False,
                         factory=ComplexRecordsProxy)
         if collection.has_key(name):
             value = collection[name]
         else:
             value = _marker
     elif ICollection.providedBy(field) and \
             IObject.providedBy(field.value_type):
         iface = field.value_type.schema
         coll_prefix = iface.__identifier__ + '.' + name
         collection = reg.collectionOfInterface(
                         iface,
                         check=False,
                         prefix=coll_prefix,
                         factory=ComplexRecordsProxy)
         value = collection.values()
         if not value:
             value = _marker
     else:
         value = reg.get(self.__prefix__ + name, _marker)
     if value is _marker:
         value = self.__schema__[name].missing_value
     return value
Ejemplo n.º 8
0
    def import_node(self, interface, child):
        """Import a single <property /> node
        """
        property_name = child.getAttribute('name')

        field = interface.get(property_name, None)
        if field is None:
            return

        field = field.bind(self.element)
        value = None

        # If we have a collection, we need to look at the value_type.
        # We look for <element>value</element> child nodes and get the
        # value from there
        if ICollection.providedBy(field):
            value_type = field.value_type
            value = []
            for element in child.childNodes:
                if element.nodeName != 'element':
                    continue
                element_value = self.extract_text(element)
                value.append(self.from_unicode(value_type, element_value))
            value = self.field_typecast(field, value)

        # Otherwise, just get the value of the <property /> node
        else:
            value = self.extract_text(child)
            value = self.from_unicode(field, value)

        field.validate(value)
        field.set(self.element, value)
Ejemplo n.º 9
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """
    value = default

    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = OrderedDict()
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)

            key_text = child.attrib.get('key', None)
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(unicode(key_text))

            value[k] = elementToValue(field.value_type, child)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element.iterchildren(tag=etree.Element):
            if noNS(child.tag.lower()) != 'element':
                continue
            parseinfo.stack.append(child)
            v = elementToValue(field.value_type, child)
            value.append(v)
            parseinfo.stack.pop()
        value = fieldTypecast(field, value)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            value = converter.fromUnicode(unicode(text))

        # handle i18n
        if isinstance(value, unicode) and parseinfo.i18n_domain is not None:
            translate_attr = ns('translate', I18N_NAMESPACE)
            domain_attr = ns('domain', I18N_NAMESPACE)
            msgid = element.attrib.get(translate_attr)
            domain = element.attrib.get(domain_attr, parseinfo.i18n_domain)
            if msgid:
                value = Message(msgid, domain=domain, default=value)
            elif translate_attr in element.attrib:
                value = Message(value, domain=domain)

    return value
Ejemplo n.º 10
0
    def import_node(self, interface, child):
        """Import a single <property /> node
        """
        property_name = child.getAttribute('name')

        field = interface.get(property_name, None)
        if field is None:
            return

        field = field.bind(self.assignment)
        value = None

        # If we have a collection, we need to look at the value_type.
        # We look for <element>value</element> child nodes and get the
        # value from there
        if ICollection.providedBy(field):
            value_type = field.value_type
            value = []
            for element in child.childNodes:
                if element.nodeName != 'element':
                    continue
                element_value = self.extract_text(element)
                value.append(self.from_unicode(value_type, element_value))
            value = self.field_typecast(field, value)

        # Otherwise, just get the value of the <property /> node
        else:
            value = self.extract_text(child)
            value = self.from_unicode(field, value)

        try:
            field.validate(value)
        except ConstraintNotSatisfied, e:
            logger.warning('"%s" value doesn\'t satisfy constaints for "%s:%s" field' % \
                (value, self.assignment.__name__, field.__name__))
Ejemplo n.º 11
0
def fixAjaxSelectWidgetDisplayMode(event):
    if (isinstance(event.widget, AjaxSelectWidget) and
            event.widget.mode == DISPLAY_MODE and event.widget.vocabulary):
        # Sanity check
        field = getattr(event.widget, 'field', None)
        if ICollection.providedBy(field):
            field = field.value_type
        if field is None or not getattr(field, 'vocabularyName', None):
            # Field doesn't know its vocabulary and SelectWidget cannot be used
            return
        # This is crazy! AjaxSelectWidget is based on select widget and
        # therefore has completely wrong display mode; Here we replace
        # the widget with SelectWidget, but is it really this hard?
        tmp = FieldWidget(
            event.widget.field,
            SelectWidget(event.widget.request),
        )
        # Do what they do in z3c.form.field update
        tmp.name = event.widget.name
        tmp.id = event.widget.id
        tmp.context = event.widget.context
        tmp.form = event.widget.form
        alsoProvides(tmp, IContextAware, IFormAware)
        tmp.ignoreContext = event.widget.ignoreContext
        tmp.ignoreRequest = event.widget.ignoreRequest
        tmp.showDefault = event.widget.showDefault
        tmp.mode = event.widget.mode
        event.widget.__class__ = SelectWidget
        event.widget.__dict__ = tmp.__dict__
        event.widget.update()
 def __setattr__(self, name, value):
     if name in self.__schema__:
         reg = self.__registry__
         field = self.__schema__.get(name)
         if IObject.providedBy(field):
             iface = field.schema
             collection = reg.collectionOfInterface(
                             iface,
                             check=False,
                             factory=ComplexRecordsProxy)
             collection[name] = value
         elif ICollection.providedBy(field) and \
                 IObject.providedBy(field.value_type):
             iface = field.value_type.schema
             # All tuple items are stored as records under
             # the coll_prefix prefix:
             coll_prefix = iface.__identifier__ + '.' + name
             collection = reg.collectionOfInterface(
                             iface,
                             check=False,
                             prefix=coll_prefix,
                             factory=ComplexRecordsProxy)
             # Clear collection before adding/updating in case of deletes.
             collection.clear()
             for idx, val in enumerate(value):
                 # val is our obj created by the z3cform factory
                 collection['r' + str(idx)] = val
         else:
             full_name = self.__prefix__ + name
             if full_name not in reg:
                 raise AttributeError(name)
             reg[full_name] = value
     else:
         self.__dict__[name] = value
Ejemplo n.º 13
0
    def import_node(self, interface, child):
        """Import a single <property /> node
        """
        property_name = child.getAttribute('name')

        field = interface.get(property_name, None)
        if field is None:
            return

        field = field.bind(self.element)
        value = None

        # If we have a collection, we need to look at the value_type.
        # We look for <element>value</element> child nodes and get the
        # value from there
        if ICollection.providedBy(field):
            value_type = field.value_type
            value = []
            for element in child.childNodes:
                if element.nodeName != 'element':
                    continue
                element_value = self.extract_text(element)
                value.append(self.from_unicode(value_type, element_value))
            value = self.field_typecast(field, value)

        # Otherwise, just get the value of the <property /> node
        else:
            value = self.extract_text(child)
            value = self.from_unicode(field, value)

        field.validate(value)
        field.set(self.element, value)
Ejemplo n.º 14
0
    def _load_widget_data(self):
        _marker = object()
        data = aq_base(self.context).data
        groups = dict((g.__name__, g) for g in self.groups)
        groupnames = [''] + groups.keys()
        for groupname in groupnames:
            group_data = data.get(groupname, None)
            if groupname is '':
                group = self
            else:
                group = groups.get(groupname)
                fieldgroup = self.definition[groupname]
                # # plone.autoform binds groups really, really late, so
                # # we are stuck with a GroupFactory object, we need to
                # # call it to get the actual group, then replace the
                # # group factory with it once we have manipulated
                # # any widget values:
                if IGroupFactory.providedBy(group):
                    idx = self.groups.index(group)
                    actual_group = group(self.context, self.request, self)
                    self.groups[idx] = group = actual_group
                    group.update()  # will populate group.widgets
                if group_data and fieldgroup.group_usage == 'grid':
                    data_widget = group.widgets.values()[0]
                    data_widget.value = getattr(group_data, 'data', [])
                    continue

            if group_data is not None:
                for formfield in group.fields.values():
                    schema_field = formfield.field
                    widgetname = formfield.__name__
                    fieldname = schema_field.__name__
                    v = getattr(group_data, fieldname, _marker)
                    if v is not _marker:
                        widget = group.widgets.get(widgetname)
                        conv = getMultiAdapter(
                            (schema_field, widget),
                            IDataConverter,
                        )
                        if not IDataGridField.providedBy(widget):
                            v = conv.toWidgetValue(v)
                        widget.value = v
                        if hasattr(widget, 'update'):
                            # may be necessary to copy value to other state,
                            # as is the case with radio button widgets
                            widget.update()
                            # multiple collection like set/list (multi-choice)
                            # has issues where SequenceWidget wants to reset
                            # widget.value during update... so we have to
                            # check the value (ugly hack) and also re-set the
                            # value for the display widget:
                            if ICollection.providedBy(schema_field):
                                widget.value = v
                                if v:
                                    term_item = [
                                        t for t in widget.items
                                        if t.get('value') == v[0]
                                    ][0]
                                    term_item['checked'] = True
Ejemplo n.º 15
0
    def _load_widget_data(self):
        _marker = object()
        data = aq_base(self.context).data
        groups = dict((g.__name__, g) for g in self.groups)
        groupnames = [''] + groups.keys()
        for groupname in groupnames:
            group_data = data.get(groupname, None)
            if groupname is '':
                group = self
            else:
                group = groups.get(groupname)
                fieldgroup = self.definition[groupname]
                # # plone.autoform binds groups really, really late, so
                # # we are stuck with a GroupFactory object, we need to
                # # call it to get the actual group, then replace the
                # # group factory with it once we have manipulated
                # # any widget values:
                if IGroupFactory.providedBy(group):
                    idx = self.groups.index(group)
                    actual_group = group(self.context, self.request, self)
                    self.groups[idx] = group = actual_group
                    group.update()  # will populate group.widgets
                if group_data and fieldgroup.group_usage == 'grid':
                    data_widget = group.widgets.values()[0]
                    data_widget.value = getattr(group_data, 'data', [])
                    continue

            if group_data is not None:
                for formfield in group.fields.values():
                    schema_field = formfield.field
                    widgetname = formfield.__name__
                    fieldname = schema_field.__name__
                    v = getattr(group_data, fieldname, _marker)
                    if v is not _marker:
                        widget = group.widgets.get(widgetname)
                        conv = getMultiAdapter(
                            (schema_field, widget),
                            IDataConverter,
                        )
                        if not IDataGridField.providedBy(widget):
                            v = conv.toWidgetValue(v)
                        widget.value = v
                        if hasattr(widget, 'update'):
                            # may be necessary to copy value to other state,
                            # as is the case with radio button widgets
                            widget.update()
                            # multiple collection like set/list (multi-choice)
                            # has issues where SequenceWidget wants to reset
                            # widget.value during update... so we have to
                            # check the value (ugly hack) and also re-set the
                            # value for the display widget:
                            if ICollection.providedBy(schema_field):
                                widget.value = v
                                if v:
                                    term_item = [
                                        t for t in widget.items
                                        if t.get('value') == v[0]
                                    ][0]
                                    term_item['checked'] = True
Ejemplo n.º 16
0
    def initialize(self):
        """Initialize the view class."""
        fieldId = self.request.get('fieldId', '').split('-')[-1]
        typeOrDottedname = self.request.get('typeOrDottedname')
        context = aq_inner(self.context)
        if typeOrDottedname == context.portal_type and shasattr(
                context, 'Schema'):
            # Archetype
            field = context.Schema().getField(fieldId)
            self.multivalued = field.multiValued
            self.widget = field.widget
        else:
            fti = queryUtility(IDexterityFTI, name=typeOrDottedname)
            if fti is None:
                # Must be a standalone z3c.form forms then.
                klass = utils.resolveDottedName(typeOrDottedname)
                field = klass(self.context,
                              self.request).fields.get(fieldId).field
                self.widget = FieldWidget(
                    field, UserAndGroupSelectionWidget(field, self.request))
                self.multivalued = ICollection.providedBy(field)
            else:
                # Dexterity
                schema = fti.lookupSchema()
                field = schema.get(fieldId)
                if field is None:
                    # The field might be defined in a behavior schema.
                    # Get the behaviors from either the context or the
                    # portal_type (but not both at the same time).
                    if self.request.get('ignoreContext'):
                        context = None
                        portal_type = typeOrDottedname
                    else:
                        portal_type = None
                    for behavior_schema in \
                            utils.getAdditionalSchemata(context, portal_type):
                        if behavior_schema is not None:
                            field = behavior_schema.get(fieldId)
                            if field is not None:
                                break
                self.widget = FieldWidget(
                    field, UserAndGroupSelectionWidget(field, self.request))
                self.multivalued = ICollection.providedBy(field)

        self.memberlookup = MemberLookup(self.context, self.request,
                                         self.widget)
Ejemplo n.º 17
0
 def update(self):
     super(AjaxSelectWidget, self).update()
     field = getattr(self, 'field', None)
     if ICollection.providedBy(self.field):
         field = self.field.value_type
     if (not self.vocabulary and field is not None and
             getattr(field, 'vocabularyName', None)):
         self.vocabulary = field.vocabularyName
Ejemplo n.º 18
0
 def update(self):
     super(AjaxSelectWidget, self).update()
     field = getattr(self, 'field', None)
     if ICollection.providedBy(self.field):
         field = self.field.value_type
     if (not self.vocabulary and field is not None
             and getattr(field, 'vocabularyName', None)):
         self.vocabulary = field.vocabularyName
Ejemplo n.º 19
0
 def field_info(self, field):
     is_col = ICollection.providedBy(field)
     vtype = field.value_type.__class__.__name__ if is_col else None
     return {
         'name': field.__name__,
         'title': field.title,
         'type': field.__class__.__name__,
         'value_type': vtype
         }
Ejemplo n.º 20
0
 def field_info(self, field):
     is_col = ICollection.providedBy(field)
     vtype = field.value_type.__class__.__name__ if is_col else None
     return {
         'name': field.__name__,
         'title': field.title,
         'type': field.__class__.__name__,
         'value_type': vtype
     }
Ejemplo n.º 21
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(AjaxSelectWidget, self)._base_args()
        args['name'] = self.name
        args['value'] = self.value
        args.setdefault('pattern_options', {})
        context = self.context
        field = None

        if IChoice.providedBy(self.field):
            args['pattern_options']['maximumSelectionSize'] = 1
            field = self.field
        elif ICollection.providedBy(self.field):
            field = self.field.value_type
        if IChoice.providedBy(field):
            args['pattern_options']['allowNewItems'] = 'false'

        args['pattern_options'] = dict_merge(self._ajaxselect_options(),
                                             args['pattern_options'])

        if field and getattr(field, 'vocabulary', None):
            form_url = self.request.getURL()
            source_url = '{0:s}/++widget++{1:s}/@@getSource'.format(
                form_url,
                self.name,
            )
            args['pattern_options']['vocabularyUrl'] = source_url

        # ISequence represents an orderable collection
        if ISequence.providedBy(self.field) or self.orderable:
            args['pattern_options']['orderable'] = True

        if self.vocabulary == 'plone.app.vocabularies.Keywords':
            membership = getToolByName(context, 'portal_membership')
            user = membership.getAuthenticatedMember()

            registry = getUtility(IRegistry)
            roles_allowed_to_add_keywords = registry.get(
                'plone.roles_allowed_to_add_keywords', set())
            roles = set(user.getRolesInContext(context))
            allowNewItems = bool(
                roles.intersection(roles_allowed_to_add_keywords), )
            args['pattern_options']['allowNewItems'] = str(
                allowNewItems, ).lower()

        return args
    def initialize(self):
        """Initialize the view class."""
        fieldId = self.request.get('fieldId','').split('-')[-1]
        typeOrDottedname = self.request.get('typeOrDottedname')
        context = aq_inner(self.context)
        if typeOrDottedname == context.portal_type and shasattr(context, 'Schema'):
            # Archetype
            field = context.Schema().getField(fieldId)
            self.multivalued = field.multiValued
            self.widget = field.widget
        else: 
            fti = queryUtility(IDexterityFTI, name=typeOrDottedname)
            if fti is None:
                # Must be a standalone z3c.form forms then.
                klass = utils.resolveDottedName(typeOrDottedname)
                field = klass(self.context, self.request).fields.get(fieldId).field
                self.widget = FieldWidget(field, UserAndGroupSelectionWidget(field, self.request))
                self.multivalued = ICollection.providedBy(field)
            else:
                # Dexterity
                schema = fti.lookupSchema()
                field = schema.get(fieldId)
                if field is None:
                    # The field might be defined in a behavior schema.
                    # Get the behaviors from either the context or the
                    # portal_type (but not both at the same time).
                    if self.request.get('ignoreContext'):
                        context = None
                        portal_type = typeOrDottedname
                    else:
                        portal_type = None
                    for behavior_schema in \
                            utils.getAdditionalSchemata(context, portal_type):
                        if behavior_schema is not None:
                            field = behavior_schema.get(fieldId)
                            if field is not None:
                                    break
                self.widget = FieldWidget(field, UserAndGroupSelectionWidget(field, self.request))
                self.multivalued = ICollection.providedBy(field)

        self.memberlookup = MemberLookup(self.context,
                                         self.request,
                                         self.widget)
Ejemplo n.º 23
0
def schema_type(description):
    name = description.__class__.__name__
    modulename = description.__class__.__module__
    if modulename.startswith('zope.schema'):
        # We hide the _bootstrap
        modulename = 'zope.schema'
    field_type = ':py:class:`%s<%s.%s>`' % (name, modulename, name)
    if ICollection.providedBy(description):
        field_type += ' of %s' % schema_type(description.value_type)
    return field_type
Ejemplo n.º 24
0
    def test_fieldref_interfaces(self):
        from plone.registry import field, FieldRef
        from plone.registry.interfaces import IFieldRef
        from zope.schema.interfaces import ICollection

        listField = field.List(value_type=field.ASCIILine())
        ref = FieldRef('some.record', listField)

        self.assertTrue(ICollection.providedBy(ref))
        self.assertTrue(IFieldRef.providedBy(ref))
Ejemplo n.º 25
0
    def test_fieldref_interfaces(self):
        from plone.registry import field, FieldRef
        from plone.registry.interfaces import IFieldRef
        from zope.schema.interfaces import ICollection

        listField = field.List(value_type=field.ASCIILine())
        ref = FieldRef('some.record', listField)

        self.assertTrue(ICollection.providedBy(ref))
        self.assertTrue(IFieldRef.providedBy(ref))
Ejemplo n.º 26
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(RelatedItemsWidget, self)._base_args()

        args['name'] = self.name
        args['value'] = self.value
        args.setdefault('pattern_options', {})

        field = None
        if IChoice.providedBy(self.field):
            args['pattern_options']['maximumSelectionSize'] = 1
            field = self.field
        elif ICollection.providedBy(self.field):
            field = self.field.value_type

        vocabulary_name = self.vocabulary

        field_name = self.field and self.field.__name__ or None

        context = self.context
        view_context = get_widget_form(self)
        # For EditForms and non-Forms (in tests), the vocabulary is looked
        # up on the context, otherwise on the view
        if (IEditForm.providedBy(view_context)
                or not IForm.providedBy(view_context)):
            view_context = context

        args['pattern_options'] = dict_merge(
            get_relateditems_options(
                view_context,
                args['value'],
                self.separator,
                vocabulary_name,
                self.vocabulary_view,
                field_name,
            ), args['pattern_options'])
        if (not self.vocabulary_override and field
                and getattr(field, 'vocabulary', None)):
            # widget vocab takes precedence over field
            form_url = self.request.getURL()
            source_url = '{0:s}/++widget++{1:s}/@@getSource'.format(
                form_url, self.name)
            args['pattern_options']['vocabularyUrl'] = source_url

        return args
Ejemplo n.º 27
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value
            - `multiple`: field multiple
            - `items`: field items from which we can select to

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(SelectWidget, self)._base_args()
        args['name'] = self.name
        args['value'] = self.value
        args['multiple'] = self.multiple

        self.required = self.field.required

        options = args.setdefault('pattern_options', {})
        if self.multiple or ICollection.providedBy(self.field):
            options['multiple'] = args['multiple'] = self.multiple = True

        # ISequence represents an orderable collection
        if ISequence.providedBy(self.field) or self.orderable:
            options['orderable'] = True

        if self.multiple:
            options['separator'] = self.separator

        # Allow to clear field value if it is not required
        if not self.required:
            options['allowClear'] = True

        base_items = self.items
        if callable(base_items):
            # items used to be a property in all widgets, then in the select
            # widget it became a method, then in a few others too, but never in
            # all, so this was reverted to let it be a property again.  Let's
            # support both here to avoid breaking on some z3c.form versions.
            # See https://github.com/zopefoundation/z3c.form/issues/44
            base_items = base_items()
        items = []
        for item in base_items:
            if not isinstance(item['content'], basestring):
                item['content'] = translate(
                    item['content'],
                    context=self.request,
                    default=item['value'])
            items.append((item['value'], item['content']))
        args['items'] = items

        return args
Ejemplo n.º 28
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """

        args = super(AjaxSelectWidget, self)._base_args()

        args["name"] = self.name
        args["value"] = self.value

        args.setdefault("pattern_options", {})

        field_name = self.field and self.field.__name__ or None

        context = self.context
        # We need special handling for AddForms
        if IAddForm.providedBy(getattr(self, "form")):
            context = self.form

        vocabulary_name = self.vocabulary
        field = None
        if IChoice.providedBy(self.field):
            args["pattern_options"]["maximumSelectionSize"] = 1
            field = self.field
        elif ICollection.providedBy(self.field):
            field = self.field.value_type
        if not vocabulary_name and field is not None:
            vocabulary_name = field.vocabularyName

        args["pattern_options"] = dict_merge(
            get_ajaxselect_options(
                context, args["value"], self.separator, vocabulary_name, self.vocabulary_view, field_name
            ),
            args["pattern_options"],
        )

        if field and getattr(field, "vocabulary", None):
            form_url = self.request.getURL()
            source_url = "%s/++widget++%s/@@getSource" % (form_url, self.name)
            args["pattern_options"]["vocabularyUrl"] = source_url

        # ISequence represents an orderable collection
        if ISequence.providedBy(self.field) or self.orderable:
            args["pattern_options"]["orderable"] = True

        return args
Ejemplo n.º 29
0
 def update(self):
     super(RelatedItemsWidget, self).update()
     field = getattr(self, 'field', None)
     if ICollection.providedBy(self.field):
         field = self.field.value_type
     if (not self.vocabulary and field is not None
             and getattr(field, 'vocabularyName', None)):
         self.vocabulary = field.vocabularyName
         self.vocabulary_override = True
     else:
         self.vocabulary = 'plone.app.vocabularies.Catalog'
Ejemplo n.º 30
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value
            - `multiple`: field multiple
            - `items`: field items from which we can select to

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(SelectWidget, self)._base_args()
        args['name'] = self.name
        args['value'] = self.value
        args['multiple'] = self.multiple

        self.required = self.field.required

        options = args.setdefault('pattern_options', {})
        if self.multiple or ICollection.providedBy(self.field):
            options['multiple'] = args['multiple'] = self.multiple = True

        # ISequence represents an orderable collection
        if ISequence.providedBy(self.field) or self.orderable:
            options['orderable'] = True

        if self.multiple:
            options['separator'] = self.separator

        # Allow to clear field value if it is not required
        if not self.required:
            options['allowClear'] = True

        base_items = self.items
        if callable(base_items):
            # items used to be a property in all widgets, then in the select
            # widget it became a method, then in a few others too, but never in
            # all, so this was reverted to let it be a property again.  Let's
            # support both here to avoid breaking on some z3c.form versions.
            # See https://github.com/zopefoundation/z3c.form/issues/44
            base_items = base_items()
        items = []
        for item in base_items:
            if not isinstance(item['content'], six.string_types):
                item['content'] = translate(item['content'],
                                            context=self.request,
                                            default=item['value'])
            items.append((item['value'], item['content']))
        args['items'] = items

        return args
Ejemplo n.º 31
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """

        args = super(AjaxSelectWidget, self)._base_args()

        args['name'] = self.name
        args['value'] = self.value

        args.setdefault('pattern_options', {})

        field_name = self.field and self.field.__name__ or None

        context = self.context
        # We need special handling for AddForms
        if IAddForm.providedBy(getattr(self, 'form')):
            context = self.form

        vocabulary_name = self.vocabulary
        field = None
        if IChoice.providedBy(self.field):
            args['pattern_options']['maximumSelectionSize'] = 1
            field = self.field
        elif ICollection.providedBy(self.field):
            field = self.field.value_type
        if not vocabulary_name and field is not None:
            vocabulary_name = field.vocabularyName

        args['pattern_options'] = dict_merge(
            get_ajaxselect_options(context, args['value'], self.separator,
                                   vocabulary_name, self.vocabulary_view,
                                   field_name),
            args['pattern_options'])

        if field and getattr(field, 'vocabulary', None):
            form_url = self.request.getURL()
            source_url = "%s/++widget++%s/@@getSource" % (form_url, self.name)
            args['pattern_options']['vocabularyUrl'] = source_url

        # ISequence represents an orderable collection
        if ISequence.providedBy(self.field) or self.orderable:
            args['pattern_options']['orderable'] = True

        return args
Ejemplo n.º 32
0
    def __call__(self, context, request):
        # Sequence widget factory
        if ICollection.providedBy(context):
            args = (context, context.value_type, request) + self.args

        # Vocabulary widget factory
        elif IChoice.providedBy(context):
            args = (context, context.vocabulary, request) + self.args

        # Regular widget factory
        else:
            args = (context, request) + self.args

        return self._create(args)
Ejemplo n.º 33
0
def _indexer_value(v, fieldtype=None):
    """General value normalizer for indexed values"""
    # check datetime, then date, order matters:
    if isinstance(v, datetime.datetime):
        return int(time.mktime(v.timetuple()))  # timetuple has 1s resolution
    if isinstance(v, datetime.date):
        return v.toordinal()
    if v is None and ICollection.implementedBy(fieldtype):
        # default value is empty list/set/tuple/dict respective to fieldtype
        return fieldtype._type()  # _type is non-tuple type for collections
    elif v is None:
        # avoid range query side effects of None key for index btrees
        return float('inf')  # sentinel value
    return v
Ejemplo n.º 34
0
    def __call__(self, context, request):
        # Sequence widget factory
        if ICollection.providedBy(context):
            args = (context, context.value_type, request) + self.args

        # Vocabulary widget factory
        elif IChoice.providedBy(context):
            args = (context, context.vocabulary, request) + self.args

        # Regular widget factory
        else:
            args = (context, request) + self.args

        return self._create(args)
Ejemplo n.º 35
0
def _indexer_value(v, fieldtype=None):
    """General value normalizer for indexed values"""
    # check datetime, then date, order matters:
    if isinstance(v, datetime.datetime):
        return int(time.mktime(v.timetuple()))  # timetuple has 1s resolution
    if isinstance(v, datetime.date):
        return v.toordinal()
    if v is None and ICollection.implementedBy(fieldtype):
        # default value is empty list/set/tuple/dict respective to fieldtype
        return fieldtype._type()  # _type is non-tuple type for collections
    elif v is None:
        # avoid range query side effects of None key for index btrees
        return float('inf')  # sentinel value
    return v
Ejemplo n.º 36
0
 def update(self):
     super(RelatedItemsWidget, self).update()
     field = getattr(self, 'field', None)
     if ICollection.providedBy(self.field):
         field = self.field.value_type
     if (
         not self.vocabulary and
         field is not None and
         getattr(field, 'vocabularyName', None)
     ):
         self.vocabulary = field.vocabularyName
         self.vocabulary_override = True
     else:
         self.vocabulary = 'plone.app.vocabularies.Catalog'
Ejemplo n.º 37
0
def valueToElement(field, value, name=None, force=False):
    """Create and return an element that describes the given value, which is
    assumed to be valid for the given field.

    If name is given, this will be used as the new element name. Otherwise,
    the field's __name__ attribute is consulted.

    If force is True, the value will always be written. Otherwise, it is only
    written if it is not equal to field.missing_value.
    """

    if name is None:
        name = field.__name__

    child = etree.Element(name)

    if value is not None and (force or value != field.missing_value):

        if IDict.providedBy(field):
            key_converter = IToUnicode(field.key_type)
            for k, v in sorted(value.items()):
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                list_element.attrib['key'] = key_converter.toUnicode(k)
                child.append(list_element)

        elif ICollection.providedBy(field):
            if ISet.providedBy(field):
                # Serliazation should be consistent even if value was not really a set
                value = sorted(value)
            for v in value:
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                child.append(list_element)

        else:
            converter = IToUnicode(field)
            child.text = converter.toUnicode(value)

            # handle i18n
            if isinstance(value, Message):
                child.set(ns('domain', I18N_NAMESPACE), value.domain)
                if not value.default:
                    child.set(ns('translate', I18N_NAMESPACE), '')
                else:
                    child.set(ns('translate', I18N_NAMESPACE), child.text)
                    child.text = converter.toUnicode(value.default)

    return child
Ejemplo n.º 38
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value
            - `multiple`: field multiple
            - `items`: field items from which we can select to

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(SelectWidget, self)._base_args()
        args['name'] = self.name
        args['value'] = self.value
        args['multiple'] = self.multiple

        self.required = self.field.required

        options = args.setdefault('pattern_options', {})
        if self.multiple or ICollection.providedBy(self.field):
            options['multiple'] = args['multiple'] = self.multiple = True

        # ISequence represents an orderable collection
        if ISequence.providedBy(self.field) or self.orderable:
            options['orderable'] = True

        if self.multiple:
            options['separator'] = self.separator

        # Allow to clear field value if it is not required
        if not self.required:
            options['allowClear'] = True

        items = []
        for item in self.items():
            if not isinstance(item['content'], basestring):
                item['content'] = translate(
                    item['content'],
                    context=self.request,
                    default=item['value'])
            items.append((item['value'], item['content']))
        args['items'] = items

        return args
Ejemplo n.º 39
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(RelatedItemsWidget, self)._base_args()

        args['name'] = self.name
        args['value'] = self.value
        args.setdefault('pattern_options', {})

        field = None
        if IChoice.providedBy(self.field):
            args['pattern_options']['maximumSelectionSize'] = 1
            field = self.field
        elif ICollection.providedBy(self.field):
            field = self.field.value_type

        vocabulary_name = self.vocabulary
        if not vocabulary_name:
            if field is not None and field.vocabularyName:
                vocabulary_name = field.vocabularyName
            else:
                vocabulary_name = 'plone.app.vocabularies.Catalog'

        field_name = self.field and self.field.__name__ or None
        args['pattern_options'] = dict_merge(
            get_relateditems_options(self.context, args['value'],
                                     self.separator, vocabulary_name,
                                     self.vocabulary_view, field_name),
            args['pattern_options'])

        if not self.vocabulary:  # widget vocab takes precedence over field
            if field and getattr(field, 'vocabulary', None):
                form_url = self.request.getURL()
                source_url = "%s/++widget++%s/@@getSource" % (
                    form_url, self.name)
                args['pattern_options']['vocabularyUrl'] = source_url

        return args
Ejemplo n.º 40
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value
            - `multiple`: field multiple
            - `items`: field items from which we can select to

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(SelectWidget, self)._base_args()
        args['name'] = self.name
        args['value'] = self.value
        args['multiple'] = self.multiple

        self.required = self.field.required

        options = args.setdefault('pattern_options', {})
        if self.multiple or ICollection.providedBy(self.field):
            options['multiple'] = args['multiple'] = self.multiple = True

        # ISequence represents an orderable collection
        if ISequence.providedBy(self.field) or self.orderable:
            options['orderable'] = True

        if self.multiple:
            options['separator'] = self.separator

        # Allow to clear field value if it is not required
        if not self.required:
            options['allowClear'] = True

        items = []
        for item in self.items():
            if not isinstance(item['content'], basestring):
                item['content'] = translate(
                    item['content'],
                    context=self.request,
                    default=item['value'])
            items.append((item['value'], item['content']))
        args['items'] = items

        return args
Ejemplo n.º 41
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(RelatedItemsWidget, self)._base_args()

        args['name'] = self.name
        args['value'] = self.value
        args.setdefault('pattern_options', {})

        field = None
        if IChoice.providedBy(self.field):
            args['pattern_options']['maximumSelectionSize'] = 1
            field = self.field
        elif ICollection.providedBy(self.field):
            field = self.field.value_type

        vocabulary_name = self.vocabulary
        if not vocabulary_name:
            if field is not None and field.vocabularyName:
                vocabulary_name = field.vocabularyName
            else:
                vocabulary_name = 'plone.app.vocabularies.Catalog'

        field_name = self.field and self.field.__name__ or None
        args['pattern_options'] = dict_merge(
            get_relateditems_options(self.context, args['value'],
                                     self.separator, vocabulary_name,
                                     self.vocabulary_view, field_name),
            args['pattern_options'])

        if not self.vocabulary:  # widget vocab takes precedence over field
            if field and getattr(field, 'vocabulary', None):
                form_url = self.request.getURL()
                source_url = "%s/++widget++%s/@@getSource" % (
                    form_url, self.name)
                args['pattern_options']['vocabularyUrl'] = source_url

        return args
Ejemplo n.º 42
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """

    value = default

    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = {}
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue

            key_text = child.attrib.get('key', None)
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(unicode(key_text))

            value[k] = elementToValue(field.value_type, child)
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue
            v = elementToValue(field.value_type, child)
            value.append(v)
        value = fieldTypecast(field, value)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            value = converter.fromUnicode(unicode(text))

    return value
Ejemplo n.º 43
0
def elementToValue(field, element, default=_marker):
    """Read the contents of an element that is assumed to represent a value
    allowable by the given field.

    If converter is given, it should be an IToUnicode instance.

    If not, the field will be adapted to this interface to obtain a converter.
    """

    value = default

    if IDict.providedBy(field):
        key_converter = IFromUnicode(field.key_type)
        value = {}
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue

            key_text = child.attrib.get('key', None)
            if key_text is None:
                k = None
            else:
                k = key_converter.fromUnicode(unicode(key_text))

            value[k] = elementToValue(field.value_type, child)
        value = fieldTypecast(field, value)

    elif ICollection.providedBy(field):
        value = []
        for child in element:
            if noNS(child.tag.lower()) != 'element':
                continue
            v = elementToValue(field.value_type, child)
            value.append(v)
        value = fieldTypecast(field, value)

    # Unicode
    else:
        text = element.text
        if text is None:
            value = field.missing_value
        else:
            converter = IFromUnicode(field)
            value = converter.fromUnicode(unicode(text))

    return value
Ejemplo n.º 44
0
def extract_fields(fields, params):
    for name, field in fields:
        value = params.get(name)

        if value is None:
            yield value
        elif ICollection.providedBy(field):
            if not isinstance(value, Iterable):
                value = [value]
            yield value
        else:
            if (isinstance(value, Iterable)
                    and not isinstance(value, (str, bytes))):
                value = value[0]
            if hasattr(field, 'fromUnicode'):
                value = field.fromUnicode(value)
            yield value
Ejemplo n.º 45
0
    def get_vocabulary(self):
        widget = self.context
        field = widget.field.bind(widget.context)

        # check field's write permission
        info = mergedTaggedValueDict(field.interface, WRITE_PERMISSIONS_KEY)
        permission_name = info.get(field.__name__, "cmf.ModifyPortalContent")
        permission = queryUtility(IPermission, name=permission_name)
        if permission is None:
            permission = getUtility(IPermission, name="cmf.ModifyPortalContent")
        if not getSecurityManager().checkPermission(permission.title, self.get_context()):
            raise VocabLookupException("Vocabulary lookup not allowed.")

        if ICollection.providedBy(field):
            return field.value_type.vocabulary
        else:
            return field.vocabulary
Ejemplo n.º 46
0
    def get_vocabulary(self):
        widget = self.context
        field = widget.field.bind(widget.context)

        # check field's write permission
        info = mergedTaggedValueDict(field.interface, WRITE_PERMISSIONS_KEY)
        permission_name = info.get(field.__name__, 'cmf.ModifyPortalContent')
        permission = queryUtility(IPermission, name=permission_name)
        if permission is None:
            permission = getUtility(IPermission,
                                    name='cmf.ModifyPortalContent')
        if not getSecurityManager().checkPermission(permission.title,
                                                    self.get_context()):
            raise VocabLookupException('Vocabulary lookup not allowed.')

        if ICollection.providedBy(field):
            return field.value_type.vocabulary
        return field.vocabulary
Ejemplo n.º 47
0
    def import_node(self, interface, child):
        """Import a single <property /> node
        """
        property_name = child.getAttribute('name')

        field = interface.get(property_name, None)
        if field is None:
            return

        field = field.bind(self.assignment)
        value = None

        # If we have a collection, we need to look at the value_type.
        # We look for <element>value</element> child nodes and get the
        # value from there
        if ICollection.providedBy(field):
            value_type = field.value_type
            value = []
            for element in child.childNodes:
                if element.nodeName != 'element':
                    continue
                element_value = self.extract_text(element)
                value.append(self.from_unicode(value_type, element_value))
            value = self.field_typecast(field, value)

        # Otherwise, just get the value of the <property /> node
        else:
            value = self.extract_text(child)
            if not (field.getName() == 'root' and value in ['', '/']):
                value = self.from_unicode(field, value)

        if field.getName() == 'root' and value in ['', '/']:
            # these valid values don't pass validation of SearchableTextSourceBinder
            field.set(self.assignment, value)
        else:
            # I don't care if it's raised on a path...
            try:
                field.validate(value)
            except ConstraintNotSatisfied:
                if type(field) == Choice and ISource.providedBy(field.source):
                    pass
                else:
                    raise
            field.set(self.assignment, value)
Ejemplo n.º 48
0
    def import_node(self, interface, child):
        """Import a single <property /> node
        """
        property_name = child.getAttribute('name')

        field = interface.get(property_name, None)
        if field is None:
            return

        field = field.bind(self.assignment)
        value = None

        # If we have a collection, we need to look at the value_type.
        # We look for <element>value</element> child nodes and get the
        # value from there
        if ICollection.providedBy(field):
            value_type = field.value_type
            value = []
            for element in child.childNodes:
                if element.nodeName != 'element':
                    continue
                element_value = self.extract_text(element)
                value.append(self.from_unicode(value_type, element_value))
            value = self.field_typecast(field, value)

        # Otherwise, just get the value of the <property /> node
        else:
            value = self.extract_text(child)
            if not (field.getName() == 'root' and value in ['', '/']):
                value = self.from_unicode(field, value)

        if field.getName() == 'root' and value in ['', '/']:
            # these valid values don't pass validation of SearchableTextSourceBinder
            field.set(self.assignment, value)
        else:
            # I don't care if it's raised on a path...
            try:
                field.validate(value)
            except ConstraintNotSatisfied:
                if type(field) == Choice and ISource.providedBy(field.source):
                    pass
                else:
                    raise
            field.set(self.assignment, value)
Ejemplo n.º 49
0
    def export_field(self, doc, field):
        """Turn a zope.schema field into a node and return it
        """
        field = field.bind(self.assignment)
        value = field.get(self.assignment)

        child = doc.createElement('property')
        child.setAttribute('name', field.__name__)

        if value is not None:
            if ICollection.providedBy(field):
                for e in value:
                    list_element = doc.createElement('element')
                    list_element.appendChild(doc.createTextNode(str(e)))
                    child.appendChild(list_element)
            else:
                child.appendChild(doc.createTextNode(unicode(value)))

        return child
Ejemplo n.º 50
0
    def export_field(self, doc, field):
        """Turn a zope.schema field into a node and return it
        """
        field = field.bind(self.assignment)
        value = field.get(self.assignment)

        child = doc.createElement('property')
        child.setAttribute('name', field.__name__)

        if value is not None:
            if ICollection.providedBy(field):
                for e in value:
                    list_element = doc.createElement('element')
                    list_element.appendChild(doc.createTextNode(str(e)))
                    child.appendChild(list_element)
            else:
                child.appendChild(doc.createTextNode(six.text_type(value)))

        return child
Ejemplo n.º 51
0
    def _base_args(self):
        """Method which will calculate _base class arguments.

        Returns (as python dictionary):
            - `pattern`: pattern name
            - `pattern_options`: pattern options
            - `name`: field name
            - `value`: field value

        :returns: Arguments which will be passed to _base
        :rtype: dict
        """
        args = super(RelatedItemsWidget, self)._base_args()

        args["name"] = self.name
        args["value"] = self.value
        args.setdefault("pattern_options", {})

        vocabulary_name = self.vocabulary
        field = None
        if IChoice.providedBy(self.field):
            args["pattern_options"]["maximumSelectionSize"] = 1
            field = self.field
        elif ICollection.providedBy(self.field):
            field = self.field.value_type
        if field is not None and field.vocabularyName:
            vocabulary_name = field.vocabularyName

        field_name = self.field and self.field.__name__ or None
        args["pattern_options"] = dict_merge(
            get_relateditems_options(
                self.context, args["value"], self.separator, vocabulary_name, self.vocabulary_view, field_name
            ),
            args["pattern_options"],
        )

        if field and getattr(field, "vocabulary", None):
            form_url = self.request.getURL()
            source_url = "%s/++widget++%s/@@getSource" % (form_url, self.name)
            args["pattern_options"]["vocabularyUrl"] = source_url

        return args
Ejemplo n.º 52
0
    def export_sub_field(self, doc, parent, field, value):
        """Turn a zope.schema field into a node and return it
        """
        if value is not None:
            if ICollection.providedBy(field):
                for e in value:
                    list_element = doc.createElement('element')
                    self.export_sub_field(doc, list_element, field.value_type, e)
                    parent.appendChild(list_element)
            elif IObject.providedBy(field):
                for name, sub_field in field.schema.namesAndDescriptions():
                    sub_value = value.get(name)
                    list_element = doc.createElement('property')
                    list_element.setAttribute('name', name)
                    self.export_sub_field(doc, list_element, sub_field, sub_value)
                    parent.appendChild(list_element)
            else:
                parent.appendChild(doc.createTextNode(unicode(value)))

        return parent
def convertRecord(record, schema):
    """Converts the QueryRecords from a query result into a dict based on the schema.
    """
    sf_fields = schema.queryTaggedValue('salesforce.fields', {})
    sf_relationships = schema.queryTaggedValue('salesforce.relationships', {})
    sf_subqueries = schema.queryTaggedValue('salesforce.subqueries', {})
    
    d = {}
    for fname in schema:
        field = schema[fname]
        if fname in sf_fields:
            
            # Determine the 'path' to the field value.
            field_parts = sf_fields[fname].split('.')
            if fname in sf_relationships.keys():
                field_parts = sf_relationships[fname].split('.') + field_parts
            
            # Try to get a corresponding value from the record.
            try:
                value = valueFromRecord(record, field_parts)
            except KeyError:
                continue
            
            d[fname] = convertToSchemaValue(field, value)
        elif fname in sf_relationships:
            if ICollection.providedBy(field) and IObject.providedBy(field.value_type):
                subschema = field.value_type.schema
                subvalues = []
                for subrecord in valueFromRecord(record, sf_relationships[fname].split('.')):
                    subvalues.append(convertRecord(subrecord, subschema))
                d[fname] = subvalues
            else:
                pass
        elif fname in sf_subqueries:
            # custom query, we don't know how to find the relevant value on
            # the record so we just give the converter the whole record and
            # let it do its thing.
            # (Things will blow up if there isn't a custom converter!)
            d[fname] = convertToSchemaValue(field, record)
    return d
Ejemplo n.º 54
0
def common_widget_updates(context):
    """
    Given a context, update field widgets for it.  Context
    May be any z3c.form instance or a field group contained
    within.
    """
    # form field filter definition:
    vtype = lambda formfield: getattr(formfield.field, 'value_type', None)
    use_vocab = lambda v: hasattr(v, '__len__') and hasattr(v, '__iter__')
    is_choice = lambda formfield: IChoice.providedBy(formfield.field)
    v_choice = lambda formfield: IChoice.providedBy(vtype(formfield))
    is_collection = lambda formfield: ICollection.providedBy(formfield.field)
    is_multi = lambda formfield: is_collection(formfield) and v_choice(
        formfield)  # noqa
    is_date = lambda formfield: IDate.providedBy(formfield.field)
    is_bool = lambda formfield: IBool.providedBy(formfield.field)

    # filtered lists of form fields by type
    formfields = context.fields.values()
    choicefields = filter(is_choice, formfields)
    multifields = filter(is_multi, formfields)
    datefields = filter(is_date, formfields)
    boolfields = filter(is_bool, formfields)

    for formfield in choicefields:
        vocab = formfield.field.vocabulary
        if use_vocab(vocab) and len(vocab) <= 6:
            formfield.widgetFactory = RadioFieldWidget

    for formfield in multifields:
        vocab = formfield.field.value_type.vocabulary
        if use_vocab(vocab) and len(vocab) <= 16:
            formfield.widgetFactory = CheckBoxFieldWidget

    for formfield in datefields:
        formfield.widgetFactory = TypeADateFieldWidget

    for formfield in boolfields:
        formfield.widgetFactory = RadioFieldWidget
Ejemplo n.º 55
0
def common_widget_updates(context):
    """
    Given a context, update field widgets for it.  Context
    May be any z3c.form instance or a field group contained
    within.
    """
    # form field filter definition:
    vtype = lambda formfield: getattr(formfield.field, 'value_type', None)
    use_vocab = lambda v: hasattr(v, '__len__') and hasattr(v, '__iter__')
    is_choice = lambda formfield: IChoice.providedBy(formfield.field)
    v_choice = lambda formfield: IChoice.providedBy(vtype(formfield))
    is_collection = lambda formfield: ICollection.providedBy(formfield.field)
    is_multi = lambda formfield: is_collection(formfield) and v_choice(formfield)  # noqa
    is_date = lambda formfield: IDate.providedBy(formfield.field)
    is_bool = lambda formfield: IBool.providedBy(formfield.field)

    # filtered lists of form fields by type
    formfields = context.fields.values()
    choicefields = filter(is_choice, formfields)
    multifields = filter(is_multi, formfields)
    datefields = filter(is_date, formfields)
    boolfields = filter(is_bool, formfields)

    for formfield in choicefields:
        vocab = formfield.field.vocabulary
        if use_vocab(vocab) and len(vocab) <= 3:
            formfield.widgetFactory = RadioFieldWidget

    for formfield in multifields:
        vocab = formfield.field.value_type.vocabulary
        if use_vocab(vocab) and len(vocab) <= 16:
            formfield.widgetFactory = CheckBoxFieldWidget

    for formfield in datefields:
        formfield.widgetFactory = TypeADateFieldWidget

    for formfield in boolfields:
        formfield.widgetFactory = RadioFieldWidget
Ejemplo n.º 56
0
def valueToElement(field, value, name=None, force=False):
    """Create and return an element that describes the given value, which is
    assumed to be valid for the given field.

    If name is given, this will be used as the new element name. Otherwise,
    the field's __name__ attribute is consulted.

    If force is True, the value will always be written. Otherwise, it is only
    written if it is not equal to field.missing_value.
    """

    if name is None:
        name = field.__name__

    child = ElementTree.Element(name)

    if value is not None and (force or value != field.missing_value):

        if IDict.providedBy(field):
            key_converter = IToUnicode(field.key_type)
            for k, v in value.items():
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                list_element.attrib['key'] = key_converter.toUnicode(k)
                child.append(list_element)

        elif ICollection.providedBy(field):
            for v in value:
                list_element = valueToElement(field.value_type, v, 'element',
                                              force)
                child.append(list_element)

        else:
            converter = IToUnicode(field)
            child.text = converter.toUnicode(value)

    return child