Beispiel #1
0
def __new__post_validate(self, REQUEST=None, errors=None):
    """Validates upload file and id
    """
    field = self.getPrimaryField()
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        try:
            field.setLanguage(field.getDefaultLang(self))
            REQUEST.form['%s_file' % field.__name__] = REQUEST.form.get(
                '%s_file' % field.getName())
        finally:
            field.resetLanguage()
            if lang is not None:
                field.setLanguage(lang)
    title = self.Schema()['title']
    if IMultilanguageField.providedBy(title):
        lang = title._v_lang
        try:
            title.setLanguage(title.getDefaultLang(self))
            REQUEST.form[title.__name__] = REQUEST.form.get(title.getName())
        finally:
            title.resetLanguage()
            if lang is not None:
                title.setLanguage(lang)
    self.__old__post_validate(REQUEST, errors)
 def __init__(self, context, request):
     super(RenameForm, self).__init__(context, request)
     for name, value in self.request.form.items():
         self.request.form[name] = safe_unicode(value)
     self.form_fields = FormFields(IRenameForm)
     self.form_name = '%s (%s)' % (self.context.Title(), self.context.getId())
     mtool = getToolByName(self.context, 'portal_membership')
     title = self.context.Schema()['title']
     self.id = self.context.getId()
     self.languages = {}
     if (IMultilanguageField.providedBy(title) or
         not mtool.checkPermission(DeleteObjects, self.context) or
         not mtool.checkPermission(copy_or_move, self.context)):
         self.form_fields = self.form_fields.omit('id')
     if (IMultilanguageField.providedBy(title) or
         not mtool.checkPermission(ModifyPortalContent, self.context)):
         self.form_fields = self.form_fields.omit('title')
     if IMultilanguageField.providedBy(title):
         self.handler = IMultilanguageURLHandler(aq_parent(aq_inner(self.context)), None)
         for lang in title.getAvailableLanguages(self.context):
             self.languages[lang['name']] = lang['title']
             self.form_fields = self.form_fields + FormFields(
                 schema.TextLine(
                     __name__=lang['name'],
                     title=lang['title'],
                     default=self.handler.get_translated_id(self.id, lang['name']),
                     required=True
                 )
             )
             self.form_fields[lang['name']].interface = IRenameForm
Beispiel #3
0
def __new_SearchableText(self, lang=None):
    """All fields marked as 'searchable' are concatenated together
    here for indexing purpose.
    """
    data = []
    charset = self.getCharset()
    for field in self.Schema().fields():
        if not field.searchable:
            continue
        method = field.getIndexAccessor(self)
        try:
            if IMultilanguageField.providedBy(field) and lang:
                field.setLanguage(lang)
            try:
                datum = method(mimetype="text/plain")
            except TypeError:
                # Retry in case typeerror was raised because accessor doesn't
                # handle the mimetype argument
                try:
                    datum = method()
                except (ConflictError, KeyboardInterrupt):
                    raise
                except:
                    continue
            if datum:
                type_datum = type(datum)
                vocab = field.Vocabulary(self)
                if isinstance(datum, list) or isinstance(datum, tuple):
                    # Unmangle vocabulary: we index key AND value
                    vocab_values = map(
                        lambda value, vocab=vocab: vocab.getValue(value, ''),
                        datum)
                    datum = list(datum)
                    datum.extend(vocab_values)
                    datum = ' '.join(datum)
                elif isinstance(datum, basestring):
                    if isinstance(datum, unicode):
                        datum = datum.encode(charset)
                    value = vocab.getValue(datum, '')
                    if isinstance(value, unicode):
                        value = value.encode(charset)
                    datum = "%s %s" % (
                        datum,
                        value,
                    )

                if isinstance(datum, unicode):
                    datum = datum.encode(charset)

                data.append(str(datum))
        finally:
            if IMultilanguageField.providedBy(field) and lang:
                field.resetLanguage()

    data = ' '.join(data)
    return data
def __new_SearchableText(self, lang=None):
    """All fields marked as 'searchable' are concatenated together
    here for indexing purpose.
    """
    data = []
    charset = self.getCharset()
    for field in self.Schema().fields():
        if not field.searchable:
            continue
        method = field.getIndexAccessor(self)
        try:
            if IMultilanguageField.providedBy(field) and lang:
                field.setLanguage(lang)
            try:
                datum = method(mimetype="text/plain")
            except TypeError:
                # Retry in case typeerror was raised because accessor doesn't
                # handle the mimetype argument
                try:
                    datum =  method()
                except (ConflictError, KeyboardInterrupt):
                    raise
                except:
                    continue
            if datum:
                type_datum = type(datum)
                vocab = field.Vocabulary(self)
                if isinstance(datum, list) or isinstance(datum, tuple):
                    # Unmangle vocabulary: we index key AND value
                    vocab_values = map(lambda value, vocab=vocab: vocab.getValue(value, ''), datum)
                    datum = list(datum)
                    datum.extend(vocab_values)
                    datum = ' '.join(datum)
                elif isinstance(datum, basestring):
                    if isinstance(datum, unicode):
                        datum = datum.encode(charset)
                    value = vocab.getValue(datum, '')
                    if isinstance(value, unicode):
                        value = value.encode(charset)
                    datum = "%s %s" % (datum, value, )

                if isinstance(datum, unicode):
                    datum = datum.encode(charset)
                    
                data.append(str(datum))
        finally:
            if IMultilanguageField.providedBy(field) and lang:
                field.resetLanguage()
            
    data = ' '.join(data)
    return data
    def kssValidateMultilanguageField(self, fieldname, uid=None):
        '''Validate a given multilanguage field
        '''
        # validate the field, actually

        if uid is not None:
            rc = getToolByName(aq_inner(self.context), 'reference_catalog')
            instance = rc.lookupObject(uid)
        else:
            deprecated(ValidationView, missing_uid_deprecation)
            instance = aq_inner(self.context)

        field = instance.getField(fieldname)
        if field.type in SKIP_KSSVALIDATION_FIELDTYPES or \
           not IMultilanguageField.providedBy(field):
            return self.render()
        value = dict([(key[key.find('___') + 3:-3], value)
                      for key, value in self.request.form.items()
                      if key.startswith(fieldname)])
        error = field.validate(value, instance, {}, REQUEST=self.request)
        # XXX
        if isinstance(error, str):
            error = error.decode('utf', 'replace')
        # replace the error on the page
        self.getCommandSet('atvalidation').issueFieldError(fieldname, error)
        return self.render()
def __bobo_traverse__(self, REQUEST, name):
    """Transparent access to multilanguage image scales for
       content types holding an multilanguage ImageField named
       'image'

       NO BLOBS
    """
    if name.startswith('image_') or name == 'image':
        field = self.getField('image')
        if not IMultilanguageField.providedBy(field):
            return BaseObject.__bobo_traverse__(self, REQUEST, name)
        last = REQUEST.get('ACTUAL_URL', '').endswith(name)
        fieldname, scale = name, None
        if '___' in name:
            fieldname, lang, scalename = name.split('___')
            if scalename:
                scale = scalename[1:]
        else:
            if '_' in name:
                fieldname, scale = name.split('_', 1)
            if last and REQUEST.get('HTTP_USER_AGENT', False):
                _scale = scale
                if _scale is not None:
                    _scale = '_'+str(_scale)
                else:
                    _scale = ''
                REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+field._getCurrentLanguage(self)+'___'+_scale)
            lang = field._getCurrentLanguage(self)
        lang_before = field._v_lang
        try:
            field.setLanguage(lang)
            image = None
            if scale:
                if scale in field.getAvailableSizes(self):
                    image = field.getScale(self, scale=scale)
            else:
                image = field.getScale(self)
            if not image: # language fallback
                defaultLang = field.getDefaultLang(self)
                if defaultLang and not defaultLang == lang:
                    field.setLanguage(defaultLang)
                    if scale:
                        if scale in field.getAvailableSizes(self):
                            image = field.getScale(self, scale=scale)
                    else:
                        image = field.getScale(self)
                if image is not None:
                    if last and REQUEST.get('HTTP_USER_AGENT', False):
                        _scale = scale
                        if _scale is not None:
                            _scale = '_'+str(_scale)
                        else:
                            _scale = ''
                        REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+defaultLang+'___'+_scale)
        finally:
            field.setLanguage(lang_before)
        if image is not None and not isinstance(image, basestring):
            # image might be None or '' for empty images
            return image
    return BaseObject.__bobo_traverse__(self, REQUEST, name)
def __bobo_traverse__(self, REQUEST, name):
    """ helper to access multilanguage image scales the old way during
        `unrestrictedTraverse` calls

        the method to be patched is '__bobo_traverse__'
    """
    if name.startswith('image_') or name == 'image':
        field = self.getField(name.split('_')[0])
        if not IMultilanguageField.providedBy(field) or not hasattr(REQUEST, 'get'):
            return BaseObject.__bobo_traverse__(self, REQUEST, name)
        last = REQUEST.get('ACTUAL_URL', '').endswith(name)
        fieldname, scale = name, None
        if '___' in name:
            fieldname, lang, scalename = name.split('___')
            if scalename:
                scale = scalename[1:]
        else:
            if '_' in name:
                fieldname, scale = name.split('_', 1)
            if last and REQUEST.get('HTTP_USER_AGENT', False):
                # begin own code
                if scale in field.getAvailableSizes(self):
                    # end own code
                    _scale = scale
                    if _scale is not None:
                        _scale = '_'+str(_scale)
                    else:
                        _scale = ''
                    REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+field._getCurrentLanguage(self)+'___'+_scale)
            lang = field._getCurrentLanguage(self)
        lang_before = field._v_lang
        try:
            field.setLanguage(lang)
            handler = IImageScaleHandler(field, None)
            image = None
            if handler is not None:
                try:
                    image = handler.getScale(self, scale)
                except AttributeError: # no image available, do not raise as there might be one available as a fallback
                    pass
            if not image: # language fallback
                defaultLang = field.getDefaultLang(self)
                if defaultLang and not defaultLang == lang:
                    field.setLanguage(defaultLang)
                    if handler is not None:
                        image = handler.getScale(self, scale)
                if image is not None:
                    if last and REQUEST.get('HTTP_USER_AGENT', False):
                        _scale = scale
                        if _scale is not None:
                            _scale = '_'+str(_scale)
                        else:
                            _scale = ''
                        REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+defaultLang+'___'+_scale)
        finally:
            field.setLanguage(lang_before)
        if image is not None:
            return image
    return BaseObject.__bobo_traverse__(self, REQUEST, name)
def __new_addField(self, field):
    lang = None
    existing_lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    existing = self.get(field.getName())
    if existing is not None and IMultilanguageField.providedBy(existing):
        existing_lang = existing._v_lang
        existing.resetLanguage()
    try:
        self.__old_addField(field)
    finally:
        if lang is not None:
            field.setLanguage(lang)
        if existing_lang is not None:
            existing.setLanguage(existing_lang)
def __new_addField(self, field):
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    self.__old_addField(field)
    if lang is not None:
        field.setLanguage(lang)
def __new__checkPropertyDupe(self, field, propname):
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    r = self.__old__checkPropertyDupe(field, propname)
    if lang is not None:
        field.setLanguage(lang)
    return r
def __new___setitem__(self, name, field):
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    assert name == field.getName()
    self.addField(field)
    if lang is not None:
        field.setLanguage(lang)
def __new__validateOnAdd(self, field):
    """Validates fields on adding and bootstrapping
    """
    lang = None
    existing_lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    existing = self.get(field.getName())
    if existing is not None and IMultilanguageField.providedBy(existing):
        existing_lang = existing._v_lang
        existing.resetLanguage()
    try:
        self.__old__validateOnAdd(field)
    finally:
        if lang is not None:
            field.setLanguage(lang)
        if existing_lang is not None:
            existing.setLanguage(existing_lang)
Beispiel #13
0
def __new_addField(self, field):
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    try:
        self.__old_addField(field)
    finally:
        if lang is not None:
            field.setLanguage(lang)
    def __blob__bobo_traverse__(self, REQUEST, name):
        """ helper to access multilanguage image scales the old way during
            `unrestrictedTraverse` calls

            the method to be patched is '__bobo_traverse__'
        """
        field = self.getField(name.split('_')[0])
        if not IMultilanguageField.providedBy(field) or not hasattr(REQUEST, 'get'):
            return BaseObject.__bobo_traverse__(self, REQUEST, name)
        last = REQUEST.get('ACTUAL_URL', '').endswith(name)
        fieldname, scale = name, None
        if '___' in name:
            fieldname, lang, scalename = name.split('___')
            if scalename:
                scale = scalename[1:]
        else:
            if '_' in name:
                fieldname, scale = name.split('_', 1)
            if last and REQUEST.get('HTTP_USER_AGENT', False):
                _scale = scale
                if _scale is not None:
                    _scale = '_'+str(_scale)
                else:
                    _scale = ''
                REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+field._getCurrentLanguage(self)+'___'+_scale)
            lang = field._getCurrentLanguage(self)
        lang_before = field._v_lang
        try:
            field.setLanguage(lang)
            handler = IImageScaleHandler(field, None)
            image = None
            if handler is not None:
                try:
                    image = handler.getScale(self, scale)
                except AttributeError: # no image available, do not raise as there might be one available as a fallback
                    pass
            if not image: # language fallback
                defaultLang = field.getDefaultLang(self)
                if defaultLang and not defaultLang == lang:
                    field.setLanguage(defaultLang)
                    if handler is not None:
                        image = handler.getScale(self, scale)
                if image is not None:
                    if last and REQUEST.get('HTTP_USER_AGENT', False):
                        _scale = scale
                        if _scale is not None:
                            _scale = '_'+str(_scale)
                        else:
                            _scale = ''
                        REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+fieldname+'___'+defaultLang+'___'+_scale)
        finally:
            field.setLanguage(lang_before)
        if image is not None:
            return image
        return BaseObject.__bobo_traverse__(self, REQUEST, name)
def __new__post_validate(self, REQUEST=None, errors=None):
    """Validates upload file and id
    """
    field  = self.getPrimaryField()
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.setLanguage(field.getDefaultLang(self))
        REQUEST.form['%s_file' % field.__name__] = REQUEST.form.get('%s_file' % field.getName())
        field.resetLanguage()
        if lang is not None:
            field.setLanguage(lang)
    title = self.Schema()['title']
    if IMultilanguageField.providedBy(title):
        lang = title._v_lang
        title.setLanguage(title.getDefaultLang(self))
        REQUEST.form[title.__name__] = REQUEST.form.get(title.getName())
        title.resetLanguage()
        if lang is not None:
            title.setLanguage(lang)
    self.__old__post_validate(REQUEST, errors)
Beispiel #16
0
def __new___setitem__(self, name, field):
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    try:
        assert name == field.getName()
        self.addField(field)
    finally:
        if lang is not None:
            field.setLanguage(lang)
Beispiel #17
0
def __new__checkPropertyDupe(self, field, propname):
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    try:
        r = self.__old__checkPropertyDupe(field, propname)
    finally:
        if lang is not None:
            field.setLanguage(lang)
    return r
Beispiel #18
0
def __new__validateOnAdd(self, field):
    """Validates fields on adding and bootstrapping
    """
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    try:
        self.__old__validateOnAdd(field)
    finally:
        if lang is not None:
            field.setLanguage(lang)
def __new__validateOnAdd(self, field):
    """Validates fields on adding and bootstrapping
    """
    lang = None
    if IMultilanguageField.providedBy(field):
        lang = field._v_lang
        field.resetLanguage()
    try:
        self.__old__validateOnAdd(field)
    finally:
        if lang is not None:
            field.setLanguage(lang)
def __new__index_html(self, REQUEST=None, RESPONSE=None):
    """Make it directly viewable when entering the objects URL
    """
    field = self.getPrimaryField()
    if not IBlobField.providedBy(field) and IMultilanguageField.providedBy(field):
        if REQUEST is None and hasattr(self, 'REQUEST'):
            REQUEST = self.REQUEST
        if REQUEST is not None and not 'lang' in REQUEST.keys():
            url = REQUEST['ACTUAL_URL']
            url += urlparse(url).query and '&' or '?'
            url += 'lang='+field._getCurrentLanguage(self)
            return REQUEST.response.redirect(url)
    return self.__old__index_html(REQUEST, RESPONSE)
Beispiel #21
0
def __new__index_html(self, REQUEST=None, RESPONSE=None):
    """Make it directly viewable when entering the objects URL
    """
    field = self.getPrimaryField()
    if not IBlobField.providedBy(field) and IMultilanguageField.providedBy(
            field):
        if REQUEST is None and hasattr(self, 'REQUEST'):
            REQUEST = self.REQUEST
        if REQUEST is not None and not 'lang' in REQUEST.keys():
            url = REQUEST['ACTUAL_URL']
            url += urlparse(url).query and '&' or '?'
            url += 'lang=' + field._getCurrentLanguage(self)
            return REQUEST.response.redirect(url)
    return self.__old__index_html(REQUEST, RESPONSE)
def migrate_object(obj):
    try:
        transaction.begin()
        fields = obj.Schema().fields()
        for field in fields:
            if IMultilanguageField.providedBy(field):
                migrate_field(field, obj)
        transaction.commit()
    except:
        transaction.abort()
        pass
    try:
        for child in obj.objectValues():
            migrate_object(child)
    except:
        pass
def migrate_object(obj):
    try:
        transaction.begin()
        fields = obj.Schema().fields()
        for field in fields:
            if IMultilanguageField.providedBy(field):
                migrate_field(field, obj)
        transaction.commit()
    except:
        transaction.abort()
        pass
    try:
        for child in obj.objectValues():
            migrate_object(child)
    except:
        pass
    def kssValidateMultilanguageField(self, fieldname, uid=None):
        '''Validate a given multilanguage field
        '''
        # validate the field, actually

        if uid is not None:
            rc = getToolByName(aq_inner(self.context), 'reference_catalog')
            instance = rc.lookupObject(uid)
        else:
            deprecated(ValidationView, missing_uid_deprecation)
            instance = aq_inner(self.context)

        field = instance.getField(fieldname)
        if field.type in SKIP_KSSVALIDATION_FIELDTYPES or \
           not IMultilanguageField.providedBy(field):
            return self.render()
        value = dict([(key[key.find('___')+3:-3], value) for key, value in self.request.form.items() if key.startswith(fieldname)])
        error = field.validate(value, instance, {}, REQUEST=self.request)
        # XXX
        if isinstance(error, str):
            error = error.decode('utf', 'replace')
        # replace the error on the page
        self.getCommandSet('atvalidation').issueFieldError(fieldname, error)
        return self.render()
 def scale(self, fieldname=None, scale=None, **parameters):
     field = self.context.getField(fieldname)
     if IMultilanguageField.providedBy(field):
         fieldname = '%s___%s___' % (fieldname, field._v_lang or field._getCurrentLanguage(getSite()))
     return self.__old_scale(fieldname, scale, **parameters)
Beispiel #26
0
def __new_validate__(self, instance, REQUEST, errors, data, metadata):
    """Validate the state of the entire object.

    The passed dictionary ``errors`` will be filled with human readable
    error messages as values and the corresponding fields' names as
    keys.

    If a REQUEST object is present, validate the field values in the
    REQUEST.  Otherwise, validate the values currently in the object.
    """
    if REQUEST:
        fieldset = REQUEST.form.get('fieldset', None)
        fieldsets = REQUEST.form.get('fieldsets', None)
    else:
        fieldset = fieldsets = None
    fields = []

    if fieldsets is not None:
        schemata = instance.Schemata()
        for fieldset in fieldsets:
            fields += [(field.getName(), field)
                       for field in schemata[fieldset].fields()]
    elif fieldset is not None:
        schemata = instance.Schemata()
        fields = [(field.getName(), field)
                  for field in schemata[fieldset].fields()]
    else:
        if data:
            fields.extend([(field.getName(), field)
                           for field in self.filterFields(isMetadata=0)])
        if metadata:
            fields.extend([(field.getName(), field)
                           for field in self.filterFields(isMetadata=1)])

    if REQUEST:
        form = REQUEST.form
    else:
        form = None

    for name, field in fields:

        # Should not validate something we can't write to anyway
        if not field.writeable(instance):
            continue

        error = 0
        value = None
        widget = field.widget

        if widget.isVisible(widget, 'edit') != 'visible':
            continue

        if form:
            result = widget.process_form(instance,
                                         field,
                                         form,
                                         empty_marker=_marker)
        else:
            result = None
        if IMultilanguageField.providedBy(field):
            value = {}
            for l, r in result[0].items():
                if r is None or r is _marker:
                    accessor = field.getEditAccessor(
                        instance) or field.getAccessor(instance)
                    if accessor is not None:
                        r = accessor()
                    else:
                        # can't get value to validate -- bail
                        continue
                value[l] = r
        else:
            if result is None or result is _marker:
                accessor = field.getEditAccessor(
                    instance) or field.getAccessor(instance)
                if accessor is not None:
                    value = accessor()
                else:
                    # can't get value to validate -- bail
                    continue
            else:
                value = result[0]

        res = field.validate(instance=instance,
                             value=value,
                             errors=errors,
                             REQUEST=REQUEST)
        if res:
            errors[field.getName()] = res
    return errors
    def get_translated_id(self, id, lang, event=True):
        """ Returns a translated ID of the object with the given ID and in the given language
        """
        id = safe_unicode(id)
        try:
            if not id in self.context:
                return id
        except:
            return id
        if not lang in self.storage:
            self.storage[lang] = OOBTree()
        if not id in self.storage[lang]:
            field = None
            try:
                obj = self.context[id]
                if IBaseObject.providedBy(obj) and (obj.isTemporary() or obj._isIDAutoGenerated(id)):
                    return id
                field = obj.Schema()['title']
                if not IMultilanguageField.providedBy(field):
                    return id

                field.setLanguage(lang)
                new_id = obj.generateNewId()
                field.resetLanguage()

                if new_id is None:
                    new_id = str('%s-%s' % (lang,id))
                if (not 'index' in self.storage or
                    not new_id in self.storage['index'] or
                    not self.storage['index'][new_id] == id) and not new_id == id:
                    invalid_id = False
                    check_id = getattr(obj, 'check_id', None)
                    if check_id is not None:
                        invalid_id = check_id(new_id, required=1)

                    # If check_id told us no, or if it was not found, make sure we have an
                    # id unique in the parent folder.
                    if invalid_id:
                        unique_id = obj._findUniqueId(new_id)
                        if unique_id is not None:
                            if check_id is None or check_id(new_id, required=1):
                                new_id = unique_id
                                invalid_id = False

                    if invalid_id:
                        new_id = id

                if self.get_actual_id(new_id) is not None:
                    new_id = '%s-%s' % (lang,new_id)
                new_id = safe_unicode(new_id)
                self.storage[lang][id] = new_id
                if not 'index' in self.storage:
                    self.storage['index'] = OOBTree()
                self.storage['index'][new_id] = id
                if event:
                    self.dispatchEvent(id)
            except ConflictError:
                if field is not None and IMultilanguageField.providedBy(field):
                    field.resetLanguage()
                raise
            except:
                if field is not None and IMultilanguageField.providedBy(field):
                    field.resetLanguage()
                return id
        return self.storage[lang][id]
def __new_validate__(self, instance, REQUEST, errors, data, metadata):
    """Validate the state of the entire object.

    The passed dictionary ``errors`` will be filled with human readable
    error messages as values and the corresponding fields' names as
    keys.

    If a REQUEST object is present, validate the field values in the
    REQUEST.  Otherwise, validate the values currently in the object.
    """
    if REQUEST:
        fieldset = REQUEST.form.get('fieldset', None)
        fieldsets = REQUEST.form.get('fieldsets', None)
    else:
        fieldset = fieldsets = None
    fields = []

    if fieldsets is not None:
        schemata = instance.Schemata()
        for fieldset in fieldsets:
            fields += [(field.getName(), field)
                       for field in schemata[fieldset].fields()]            
    elif fieldset is not None:
        schemata = instance.Schemata()
        fields = [(field.getName(), field)
                  for field in schemata[fieldset].fields()]            
    else:
        if data:
            fields.extend([(field.getName(), field)
                           for field in self.filterFields(isMetadata=0)])
        if metadata:
            fields.extend([(field.getName(), field)
                           for field in self.filterFields(isMetadata=1)])

    if REQUEST:
        form = REQUEST.form
    else:
        form = None
        
    for name, field in fields:
        
        # Should not validate something we can't write to anyway
        if not field.writeable(instance):
            continue
        
        error = 0
        value = None
        widget = field.widget
        
        if widget.isVisible(widget, 'edit') != 'visible':
            continue
        
        if form:
            result = widget.process_form(instance, field, form,
                                         empty_marker=_marker)
        else:
            result = None
        if IMultilanguageField.providedBy(field):
            value = {}
            for l, r in result[0].items():
                if r is None or r is _marker:
                    accessor = field.getEditAccessor(instance) or field.getAccessor(instance)
                    if accessor is not None:
                        r = accessor()
                    else:
                        # can't get value to validate -- bail
                        continue
                value[l] = r
        else:
            if result is None or result is _marker:
                accessor = field.getEditAccessor(instance) or field.getAccessor(instance)
                if accessor is not None:
                    value = accessor()
                else:
                    # can't get value to validate -- bail
                    continue
            else:
                value = result[0]

        res = field.validate(instance=instance,
                             value=value,
                             errors=errors,
                             REQUEST=REQUEST)
        if res:
            errors[field.getName()] = res
    return errors