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: |