web/views/basecontrollers.py
branchstable
changeset 2240 ff84892900ac
parent 2079 aff0950c54c4
child 2255 c346af0727ca
equal deleted inserted replaced
2239:0f12f1ebf27c 2240:ff84892900ac
   176                 rql = 'SET Y %s X WHERE X eid %%(x)s, Y eid %%(y)s' % rtype
   176                 rql = 'SET Y %s X WHERE X eid %%(x)s, Y eid %%(y)s' % rtype
   177             for teid in eids:
   177             for teid in eids:
   178                 req.execute(rql, {'x': eid, 'y': typed_eid(teid)}, ('x', 'y'))
   178                 req.execute(rql, {'x': eid, 'y': typed_eid(teid)}, ('x', 'y'))
   179 
   179 
   180 
   180 
       
   181 def _validation_error(req, ex):
       
   182     forminfo = req.get_session_data(req.form.get('__errorurl'), pop=True)
       
   183     foreid = ex.entity
       
   184     eidmap = req.data.get('eidmap', {})
       
   185     for var, eid in eidmap.items():
       
   186         if foreid == eid:
       
   187             foreid = var
       
   188             break
       
   189     return (foreid, ex.errors)
       
   190 
       
   191 def _validate_form(req, vreg):
       
   192     # XXX should use the `RemoteCallFailed` mechanism
       
   193     try:
       
   194         ctrl = vreg.select(vreg.registry_objects('controllers', 'edit'),
       
   195                            req=req)
       
   196     except NoSelectableObject:
       
   197         return (False, {None: req._('not authorized')})
       
   198     try:
       
   199         ctrl.publish(None, fromjson=True)
       
   200     except ValidationError, ex:
       
   201         req.cnx.rollback()
       
   202         return (False, _validation_error(req, ex))
       
   203     except Redirect, ex:
       
   204         try:
       
   205             req.cnx.commit() # ValidationError may be raise on commit
       
   206         except ValidationError, ex:
       
   207             req.cnx.rollback()
       
   208             return (False, _validation_error(req, ex))
       
   209         else:
       
   210             return (True, ex.location)
       
   211     except Exception, ex:
       
   212         req.cnx.rollback()
       
   213         req.exception('unexpected error while validating form')
       
   214         return (False, req._(str(ex).decode('utf-8')))
       
   215     return (False, '???')
       
   216 
       
   217 
   181 class FormValidatorController(Controller):
   218 class FormValidatorController(Controller):
   182     id = 'validateform'
   219     id = 'validateform'
   183 
   220 
   184     def publish(self, rset=None):
   221     def publish(self, rset=None):
   185         vreg = self.vreg
   222         # XXX unclear why we have a separated controller here vs
   186         try:
   223         # js_validate_form on the json controller
   187             ctrl = vreg.select(vreg.registry_objects('controllers', 'edit'),
   224         status, args = _validate_form(self.req, self.vreg)
   188                                req=self.req, appli=self.appli)
       
   189         except NoSelectableObject:
       
   190             status, args = (False, {None: self.req._('not authorized')})
       
   191         else:
       
   192             try:
       
   193                 ctrl.publish(None, fromjson=True)
       
   194             except ValidationError, err:
       
   195                 status, args = self.validation_error(err)
       
   196             except Redirect, err:
       
   197                 try:
       
   198                     self.req.cnx.commit() # ValidationError may be raise on commit
       
   199                 except ValidationError, err:
       
   200                     status, args = self.validation_error(err)
       
   201                 else:
       
   202                     status, args = (True, err.location)
       
   203             except Exception, err:
       
   204                 self.req.cnx.rollback()
       
   205                 self.exception('unexpected error in validateform')
       
   206                 try:
       
   207                     status, args = (False, self.req._(unicode(err)))
       
   208                 except UnicodeError:
       
   209                     status, args = (False, repr(err))
       
   210             else:
       
   211                 status, args = (False, '???')
       
   212         self.req.set_content_type('text/html')
   225         self.req.set_content_type('text/html')
   213         jsarg = simplejson.dumps( (status, args) )
   226         jsarg = simplejson.dumps( (status, args) )
   214         domid = self.req.form.get('__domid', 'entityForm').encode(
   227         domid = self.req.form.get('__domid', 'entityForm').encode(
   215             self.req.encoding)
   228             self.req.encoding)
   216         return """<script type="text/javascript">
   229         return """<script type="text/javascript">
   217  window.parent.handleFormValidationResponse('%s', null, null, %s);
   230  window.parent.handleFormValidationResponse('%s', null, null, %s);
   218 </script>""" %  (domid, simplejson.dumps( (status, args) ))
   231 </script>""" %  (domid, simplejson.dumps( (status, args) ))
   219 
       
   220     def validation_error(self, err):
       
   221         self.req.cnx.rollback()
       
   222         try:
       
   223             eid = err.entity.eid
       
   224         except AttributeError:
       
   225             eid = err.entity
       
   226         return (False, (eid, err.errors))
       
   227 
   232 
   228 
   233 
   229 class JSonController(Controller):
   234 class JSonController(Controller):
   230     id = 'json'
   235     id = 'json'
   231 
   236 
   375     @jsonize
   380     @jsonize
   376     def js_validate_form(self, action, names, values):
   381     def js_validate_form(self, action, names, values):
   377         return self.validate_form(action, names, values)
   382         return self.validate_form(action, names, values)
   378 
   383 
   379     def validate_form(self, action, names, values):
   384     def validate_form(self, action, names, values):
   380         # XXX this method (and correspoding js calls) should use the new
       
   381         #     `RemoteCallFailed` mechansim
       
   382         self.req.form = self._rebuild_posted_form(names, values, action)
   385         self.req.form = self._rebuild_posted_form(names, values, action)
   383         vreg = self.vreg
   386         return _validate_form(self.req, self.vreg)
   384         try:
       
   385             ctrl = vreg.select(vreg.registry_objects('controllers', 'edit'),
       
   386                                req=self.req)
       
   387         except NoSelectableObject:
       
   388             return (False, {None: self.req._('not authorized')})
       
   389         try:
       
   390             ctrl.publish(None, fromjson=True)
       
   391         except ValidationError, err:
       
   392             self.req.cnx.rollback()
       
   393             return (False, (err.entity, err.errors))
       
   394         except Redirect, redir:
       
   395             return (True, redir.location)
       
   396         except Exception, err:
       
   397             self.req.cnx.rollback()
       
   398             self.exception('unexpected error in js_validateform')
       
   399             return (False, self.req._(str(err).decode('utf-8')))
       
   400         return (False, '???')
       
   401 
   387 
   402     @jsonize
   388     @jsonize
   403     def js_edit_field(self, action, names, values, rtype, eid, default):
   389     def js_edit_field(self, action, names, values, rtype, eid, default):
   404         success, args = self.validate_form(action, names, values)
   390         success, args = self.validate_form(action, names, values)
   405         if success:
   391         if success: