# need this to initialize new BU for tests from Products.Archetypes.tests.test_classgen import Dummy from Products.Archetypes import atapi from Products.Archetypes.config import PKG_NAME, LANGUAGE_DEFAULT from Products.Archetypes.interfaces.layer import ILayerContainer from Products.CMFCore import permissions from Products.Archetypes.ExtensibleMetadata import FLOOR_DATE from Products.Archetypes.ExtensibleMetadata import CEILING_DATE from Products.validation import ValidationChain from DateTime import DateTime Dummy.schema = atapi.BaseSchema EmptyValidator = ValidationChain('isEmpty') EmptyValidator.appendSufficient('isEmpty') class BaseSchemaTest(ATSiteTestCase): def afterSetUp(self): ATSiteTestCase.afterSetUp(self) atapi.registerType(Dummy, 'Archetypes') content_types, constructors, ftis = atapi.process_types(atapi.listTypes(), PKG_NAME) portal = self.portal dummy = Dummy(oid='dummy') # put dummy in context of portal dummy = dummy.__of__(portal) portal.dummy = dummy
# need this to initialize new BU for tests from Products.Archetypes.tests.test_classgen import Dummy from Products.Archetypes import atapi from Products.Archetypes.config import PKG_NAME, LANGUAGE_DEFAULT from Products.Archetypes.interfaces.layer import ILayerContainer from Products.CMFCore import permissions from Products.Archetypes.ExtensibleMetadata import FLOOR_DATE from Products.Archetypes.ExtensibleMetadata import CEILING_DATE from Products.validation import ValidationChain from DateTime import DateTime Dummy.schema = atapi.BaseSchema EmptyValidator = ValidationChain('isEmpty') EmptyValidator.appendSufficient('isEmpty') class BaseSchemaTest(ATSiteTestCase): def afterSetUp(self): ATSiteTestCase.afterSetUp(self) atapi.registerType(Dummy, 'Archetypes') content_types, constructors, ftis = atapi.process_types( atapi.listTypes(), PKG_NAME) portal = self.portal dummy = Dummy(oid='dummy') # put dummy in context of portal dummy = dummy.__of__(portal) portal.dummy = dummy
def dcEdit(obj): """dublin core edit (inplace) """ obj.setTitle('Test title') obj.setDescription('Test description') obj.setSubject('Test subject') obj.setContributors(('test user a',)) obj.setEffectiveDate(DateTime() - 1) obj.setExpirationDate(DateTime() + 2) obj.setFormat('text/structured') obj.setLanguage('de') obj.setRights('GPL') from Products.validation import ValidationChain EmptyValidator = ValidationChain('isEmpty') EmptyValidator.appendSufficient('isEmpty') idValidator = ValidationChain('isValidId') idValidator.appendSufficient('isEmptyNoError') idValidator.appendRequired('isValidId') TidyHTMLValidator = ValidationChain('isTidyHtmlChain') TidyHTMLValidator.appendRequired('isTidyHtmlWithCleanup') NotRequiredTidyHTMLValidator = ValidationChain('isTidyHtmlNotRequiredChain') NotRequiredTidyHTMLValidator.appendSufficient('isEmptyNoError') NotRequiredTidyHTMLValidator.appendRequired('isTidyHtmlWithCleanup') URLValidator = ValidationChain('isURL') URLValidator.appendSufficient('isEmptyNoError') URLValidator.appendRequired('isURL') EmailValidator = ValidationChain('isEmailChain') EmailValidator.appendSufficient('isEmptyNoError') EmailValidator.appendSufficient('isMailto')
class RecordField(ObjectField): """A field that stores a 'record' (dictionary-like) construct""" _properties = ObjectField._properties.copy() _properties.update({ 'type': 'record', 'default': {}, 'subfields': (), 'subfield_types': {}, 'subfield_vocabularies': {}, 'subfield_labels': {}, 'subfield_sizes': {}, 'subfield_maxlength': {}, 'required_subfields': (), 'subfield_validators': {}, 'subfield_conditions': {}, 'innerJoin': ', ', 'outerJoin': ', ', 'widget': RecordWidget, }) security = ClassSecurityInfo() security.declarePublic('getSubfields') def getSubfields(self): """the tuple of sub-fields""" return self.subfields security.declarePublic('getSubfieldType') def getSubfieldType(self, subfield): """ optional type declaration default: string """ return self.subfield_types.get(subfield, 'string') security.declarePublic('getSubfieldLabel') def getSubfieldLabel(self, subfield): """ optional custom label for the subfield default: the id of the subfield """ return self.subfield_labels.get(subfield, subfield.capitalize()) def getSubfieldSize(self, subfield, default=40): """ optional custom size for the subfield default: 40 only effective for string type subfields """ return self.subfield_sizes.get(subfield, default) def getSubfieldMaxlength(self, subfield): """ otional custom maxlength size for the subfield only effective for string type subfields """ return self.subfield_maxlength.get(subfield, 40) def isRequired(self, subfield): """ looks whether subfield is included in the list of required subfields """ return subfield in self.required_subfields def isSelection(self, subfield): """select box needed?""" return self.subfield_vocabularies.has_key(subfield) security.declarePublic('testSubfieldCondition') def testSubfieldCondition(self, subfield, folder, portal, object): """Test the subfield condition.""" try: condition = self.subfield_conditions.get(subfield, None) if condition is not None: __traceback_info__ = (folder, portal, object, condition) ec = createExprContext(folder, portal, object) return Expression(condition)(ec) else: return True except AttributeError: return True def getVocabularyFor(self, subfield, instance=None): """the vocabulary (DisplayList) for the subfield""" ## XXX rr: couldn't we just rely on the field's ## Vocabulary method here? value = None vocab = self.subfield_vocabularies.get(subfield, None) if not vocab: raise AttributeError, 'no vocabulary found for %s' % subfield if isinstance(vocab, DisplayList): return vocab if type(vocab) in StringTypes: value = None method = getattr(self, vocab, None) if method and callable(method): value = method(instance) else: if instance is not None: method = getattr(instance, vocab, None) if method and callable(method): value = method() if not isinstance(value, DisplayList): raise TypeError, '%s is not a DisplayList %s' % (value, subfield) return value raise TypeError, '%s niether a StringType or a DisplayList for %s' % ( vocab, subfield) def getViewFor(self, instance, subfield, joinWith=', '): """ formatted value of the subfield for display """ raw = self.getRaw(instance).get(subfield, '') if type(raw) in (type(()), type([])): raw = joinWith.join(raw) # Prevent XSS attacks by quoting all user input raw = html_quote(str(raw)) # this is now very specific if subfield == 'email': return self.hideEmail(raw, instance) if subfield == 'phone': return self.labelPhone(raw) if subfield == 'fax': return self.labelFax(raw) if subfield == 'homepage': return '<a href="%s">%s</a>' % (raw, raw) return raw def getSubfieldViews(self, instance, joinWith=', '): """ list of subfield views for non-empty subfields """ result = [] for subfield in self.getSubfields(): view = self.getViewFor(instance, subfield, joinWith) if view: result.append(view) return result # this is really special purpose and in no ways generic def hideEmail(self, email='', instance=None): masked = 'email: ' + \ email.replace('@', ' (at) ').replace('.', ' (dot) ') membertool = getToolByName(instance, 'portal_membership', None) if membertool is None or membertool.isAnonymousUser(): return masked return "<a href='mailto:%s'>%s</a>" % (email, email) def labelPhone(self, phone=''): return 'phone: ' + phone def labelFax(self, fax=''): return 'fax: ' + fax # enable also a string representation of a dictionary # to be passed in (external edit may need this) # store string values as unicode def set(self, instance, value, **kwargs): if type(value) in StringTypes: try: value = eval(value) # more checks to add? except: # what to catch here? pass value = self._to_dict(value) value = self._decode_strings(value, instance, **kwargs) ObjectField.set(self, instance, value, **kwargs) def _to_dict(self, value): if type(value) != type({}) and hasattr(value, 'keys'): new_value = {} new_value.update(value) return new_value return value def _decode_strings(self, value, instance, **kwargs): new_value = value for k, v in value.items(): if type(v) is type(''): nv = decode(v, instance, **kwargs) try: new_value[k] = nv except AttributeError: # Records don't provide __setitem__ setattr(new_value, k, nv) # convert datetimes if self.subfield_types.get(k, None) == 'datetime': try: val = DateTime(v) except: val = None new_value[k] = val return new_value # Return strings using the site's encoding def get(self, instance, **kwargs): value = ObjectField.get(self, instance, **kwargs) return self._encode_strings(value, instance, **kwargs) def _encode_strings(self, value, instance, **kwargs): new_value = value for k, v in value.items(): if type(v) is type(u''): nv = encode(v, instance, **kwargs) try: new_value[k] = nv except AttributeError: # Records don't provide __setitem__ setattr(new_value, k, nv) return new_value if HAS_VALIDATION_CHAIN: def _validationLayer(self): """ Resolve that each validator is in the service. If validator is not, log a warning. We could replace strings with class refs and keep things impl the ivalidator in the list. Note: XXX this is not compat with aq_ things like scripts with __call__ """ for subfield in self.getSubfields(): self.subfield_validators[ subfield] = self._subfieldValidationLayer(subfield) def _subfieldValidationLayer(self, subfield): """ for the individual subfields """ chainname = 'Validator_%s_%s' % (self.getName(), subfield) current_validators = self.subfield_validators.get(subfield, ()) if type(current_validators) is DictType: raise NotImplementedError, 'Please use the new syntax with validation chains' elif providedBy(IValidationChain, current_validators): validators = current_validators elif providedBy(IValidator, current_validators): validators = ValidationChain(chainname, validators=current_validators) elif type(current_validators) in (TupleType, ListType, StringType): if len(current_validators): # got a non empty list or string - create a chain try: validators = ValidationChain( chainname, validators=current_validators) except (UnknowValidatorError, FalseValidatorError), msg: log("WARNING: Disabling validation for %s/%s: %s" % (self.getName(), subfield, msg)) validators = () else: validators = () else: log('WARNING: Unknow validation %s. Disabling!' % current_validators) validators = () if not subfield in self.required_subfields: if validators == (): validators = ValidationChain(chainname) if len(validators): # insert isEmpty validator at position 0 if first validator # is not isEmpty if not validators[0][0].name == 'isEmpty': validators.insertSufficient('isEmpty') else: validators.insertSufficient('isEmpty') return validators