Back to index

plone3  3.1.7
validation.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 # Copyright (c) 2006
00003 # Authors:
00004 #   Christian Klinger <cklinger@novareto.de>, goschtl
00005 #   Balazs Ree <ree@greenfinity.hu>
00006 #
00007 # This program is free software; you can redistribute it and/or modify
00008 # it under the terms of the GNU General Public License version 2 as published
00009 # by the Free Software Foundation.
00010 #
00011 # This program is distributed in the hope that it will be useful,
00012 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 # GNU General Public License for more details.
00015 #
00016 # You should have received a copy of the GNU General Public License
00017 # along with this program; if not, write to the Free Software
00018 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00019 # 02111-1307, USA.
00020 #
00021 
00022 from zope.interface import implements
00023 
00024 from Acquisition import aq_inner
00025 from Products.CMFCore.utils import getToolByName
00026 from Products.CMFPlone import PloneMessageFactory as _
00027 
00028 from plone.app.kss.plonekssview import PloneKSSView
00029 from plone.app.kss.interfaces import IPloneKSSView
00030 
00031 SKIP_KSSVALIDATION_FIELDTYPES = ('image', 'file')
00032 
00033 from zope.deprecation import deprecated
00034 
00035 missing_uid_deprecation = \
00036 "This view does not provide a KSS instance UID as required. Falling back to "
00037 "the global context on inline-editing will be removed in Plone 4.0. Please "
00038 "update your templates."
00039 
00040 class ValidationView(PloneKSSView):
00041 
00042     implements(IPloneKSSView)
00043     
00044     # --
00045     # Kss methods
00046     # --
00047 
00048     def kssValidateField(self, fieldname, value, uid=None):
00049         '''Validate a given field
00050         '''
00051         # validate the field, actually
00052 
00053         if uid is not None:
00054             rc = getToolByName(aq_inner(self.context), 'reference_catalog')
00055             instance = rc.lookupObject(uid)
00056         else:
00057             deprecated(ValidationView, missing_uid_deprecation)
00058             instance = aq_inner(self.context)
00059 
00060         field = instance.getField(fieldname)
00061         if field.type in SKIP_KSSVALIDATION_FIELDTYPES:
00062             return self.render()
00063         error = field.validate(value, instance, {})
00064         # XXX
00065         if isinstance(error, str):
00066             error = error.decode('utf', 'replace')
00067         # replace the error on the page
00068         self.getCommandSet('atvalidation').issueFieldError(fieldname, error)
00069         return self.render()
00070 
00071     # XXX full form validation
00072     def kssValidateForm(self, data):
00073         # Put the form vars on the request, as AT cannot work
00074         # from data
00075         self.request.form.update(data)
00076         # Check for Errors
00077         #errors = self.context.aq_inner.validate(self.request, errors={}, data=1, metadata=0)
00078         # this will skip some events but we don't care
00079         # the predicates should be passed from BaseObject.validate too
00080         instance = aq_inner(self.context)
00081         schema = instance.Schema()
00082         errors = validate(schema, instance, self.request, errors={}, data=1, metadata=0,
00083                 predicates=(lambda field: field.type not in SKIP_KSSVALIDATION_FIELDTYPES, ))
00084         ksscore = self.getCommandSet('core')
00085         if errors:
00086             # give the portal message
00087             self.getCommandSet('plone').issuePortalMessage(
00088                 _(u'Please correct the indicated errors.'))
00089             # reset all error fields (as we only know the error ones.)
00090             ksscore.clearChildNodes(ksscore.getCssSelector('div.field div.fieldErrorBox'))
00091             # Set error fields
00092             for fieldname, error in errors.iteritems():
00093                 # XXX
00094                 if isinstance(error, str):
00095                     error = error.decode('utf', 'replace')
00096                 self.getCommandSet('atvalidation').issueFieldError(fieldname, error)
00097         else:
00098             # I just resubmit the form then
00099             # XXX of course this should be handled from here, save the
00100             # content and redirect already to the result page - I guess
00101             # I just don't want to clean up AT form submit procedures
00102             self.commands.addCommand('plone-submitCurrentForm', ksscore.getSelector('samenode', ''))
00103         return self.render()
00104 
00105 
00106 # This is modified from Archetypes.Schema.validate
00107 
00108 class _marker:
00109     ''
00110 
00111 def validate(self, instance=None, REQUEST=None,
00112              errors=None, data=None, metadata=None, predicates=()):
00113     """Validate the state of the entire object.
00114 
00115     The passed dictionary ``errors`` will be filled with human readable
00116     error messages as values and the corresponding fields' names as
00117     keys.
00118 
00119     If a REQUEST object is present, validate the field values in the
00120     REQUEST.  Otherwise, validate the values currently in the object.
00121     """
00122     if REQUEST:
00123         fieldset = REQUEST.form.get('fieldset', None)
00124     else:
00125         fieldset = None
00126     fields = []
00127 
00128     if fieldset is not None:
00129         schemata = instance.Schemata()
00130         fields = [(field.getName(), field)
00131                   for field in schemata[fieldset].fields() 
00132                       if not [pred for pred in predicates if not pred(field)]
00133                  ]
00134 
00135     else:
00136         if data:
00137             fields.extend([(field.getName(), field)
00138                            for field in self.filterFields(isMetadata=0, *predicates)])
00139         if metadata:
00140             fields.extend([(field.getName(), field)
00141                            for field in self.filterFields(isMetadata=1, *predicates)])
00142 
00143     if REQUEST:
00144         form = REQUEST.form
00145     else:
00146         form = None
00147     for name, field in fields:
00148         error = 0
00149         value = None
00150         widget = field.widget
00151         if form:
00152             result = widget.process_form(instance, field, form,
00153                                          empty_marker=_marker)
00154         else:
00155             result = None
00156         if result is None or result is _marker:
00157             accessor = field.getEditAccessor(instance) or field.getAccessor(instance)
00158             if accessor is not None:
00159                 value = accessor()
00160             else:
00161                 # can't get value to validate -- bail
00162                 continue
00163         else:
00164             value = result[0]
00165 
00166         res = field.validate(instance=instance,
00167                              value=value,
00168                              errors=errors,
00169                              REQUEST=REQUEST)
00170         if res:
00171             errors[field.getName()] = res
00172     return errors