forms: always enable drafts (#27476)
This commit is contained in:
parent
1bcfd42502
commit
08ea74c03c
|
@ -1369,7 +1369,7 @@ def test_user_drafts(pub, local_user):
|
|||
formdef.store()
|
||||
resp = get_app(pub).get(sign_uri('/api/user/drafts', user=local_user))
|
||||
assert resp.json['err'] == 0
|
||||
assert len(resp.json['data']) == 0
|
||||
assert len(resp.json['data']) == 1
|
||||
|
||||
formdef.enable_tracking_codes = True
|
||||
formdef.disabled = True
|
||||
|
|
|
@ -1715,12 +1715,6 @@ def test_form_direct_draft_access(pub):
|
|||
formdata.store()
|
||||
resp = login(get_app(pub), 'foo', 'foo').get('/test/%s' % formdata.id, status=403)
|
||||
|
||||
formdata.user_id = user.id
|
||||
formdata.store()
|
||||
formdef.enable_tracking_codes = False
|
||||
formdef.store()
|
||||
resp = login(get_app(pub), 'foo', 'foo').get('/test/%s' % formdata.id, status=403)
|
||||
|
||||
def form_password_field_submit(pub, password):
|
||||
password = unicode(password).encode(pub.site_charset)
|
||||
formdef = create_formdef()
|
||||
|
@ -1959,7 +1953,7 @@ def test_preview_form(pub):
|
|||
next_page = next_page.forms[0].submit('submit')
|
||||
assert next_page.status_int == 302
|
||||
assert next_page.location == 'http://example.net/preview/test/'
|
||||
assert formdef.data_class().count() == 0
|
||||
assert len([x for x in formdef.data_class().select() if not x.is_draft()]) == 0
|
||||
|
||||
def test_form_item_data_source_field_submit(pub):
|
||||
def submit_item_data_source_field(ds):
|
||||
|
@ -4388,8 +4382,9 @@ def test_form_page_profile_verified_prefill(pub):
|
|||
resp.form['f0'].value = 'Hello' # try again changing the value
|
||||
resp = resp.form.submit('submit')
|
||||
|
||||
assert formdef.data_class().count() == 1
|
||||
assert formdef.data_class().select()[0].data['0'] == 'foo@localhost'
|
||||
formdatas = [x for x in formdef.data_class().select() if not x.is_draft()]
|
||||
assert len(formdatas) == 1
|
||||
assert formdatas[0].data['0'] == 'foo@localhost'
|
||||
|
||||
resp = login(get_app(pub), username='foo', password='foo').get('/test/')
|
||||
assert resp.form['f0'].value == 'foo@localhost'
|
||||
|
@ -4444,8 +4439,9 @@ def test_form_page_profile_verified_date_prefill(pub):
|
|||
resp.form['f0'].value = '2018-09-24' # try again changing the value
|
||||
resp = resp.form.submit('submit')
|
||||
|
||||
assert formdef.data_class().count() == 1
|
||||
assert time.strftime('%Y-%m-%d', formdef.data_class().select()[0].data['0']) == '2018-09-27'
|
||||
formdatas = [x for x in formdef.data_class().select() if not x.is_draft()]
|
||||
assert len(formdatas) == 1
|
||||
assert time.strftime('%Y-%m-%d', formdatas[0].data['0']) == '2018-09-27'
|
||||
|
||||
def test_form_page_profile_verified_radio_item_prefill(pub):
|
||||
user = create_user(pub)
|
||||
|
|
|
@ -611,7 +611,7 @@ class ApiUserDirectory(Directory):
|
|||
if form.is_draft():
|
||||
if not include_drafts:
|
||||
continue
|
||||
if form.formdef.is_disabled() or not form.formdef.enable_tracking_codes:
|
||||
if form.formdef.is_disabled():
|
||||
# the form or its draft support has been disabled
|
||||
continue
|
||||
elif not include_non_drafts:
|
||||
|
|
|
@ -232,6 +232,14 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
return True
|
||||
return False
|
||||
|
||||
def has_draft_support(self):
|
||||
if self.edit_mode:
|
||||
return False
|
||||
if self.formdef.enable_tracking_codes:
|
||||
return True
|
||||
session = get_session()
|
||||
return session.has_user()
|
||||
|
||||
def step(self, step_no, current_page):
|
||||
get_logger().info('form %s - step %s' % (self.formdef.name, step_no))
|
||||
|
||||
|
@ -284,7 +292,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
magictoken = get_request().form.get('magictoken')
|
||||
if magictoken:
|
||||
form_data = session.get_by_magictoken(magictoken, {})
|
||||
if self.formdef.enable_tracking_codes and not self.edit_mode:
|
||||
if self.has_draft_support():
|
||||
form.attrs['data-has-draft'] = 'yes'
|
||||
else:
|
||||
form_data = {}
|
||||
|
@ -400,7 +408,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
form.add_hidden('page_id', page.id)
|
||||
|
||||
form.add_submit('cancel', _('Cancel'), css_class = 'cancel')
|
||||
if self.formdef.enable_tracking_codes and not self.edit_mode:
|
||||
if self.has_draft_support():
|
||||
form.add_submit('savedraft', _('Save Draft'), css_class = 'save-draft',
|
||||
attrs={'style': 'display: none'})
|
||||
|
||||
|
@ -410,7 +418,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
'form_side': lambda: self.form_side(0, page, data=data, magictoken=magictoken),
|
||||
'steps': lambda: self.step(0, page),
|
||||
}
|
||||
if self.formdef.enable_tracking_codes and data:
|
||||
if self.has_draft_support() and data:
|
||||
context['tracking_code_box'] = lambda: self.tracking_code_box(data, magictoken)
|
||||
|
||||
return template.QommonTemplateResponse(
|
||||
|
@ -422,7 +430,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
(tracking code and steps).'''
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<div id="side">')
|
||||
if self.formdef.enable_tracking_codes and data:
|
||||
if self.has_draft_support() and data:
|
||||
# display tracking code box if they are enabled and there's some
|
||||
# data (e.g. the user is not on a insufficient authenticiation
|
||||
# context page)
|
||||
|
@ -433,33 +441,39 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
|
||||
def tracking_code_box(self, data, magictoken):
|
||||
'''Create the tracking code box, it displays the current tracking code
|
||||
and a 'remove draft' button if the current form is a draft that has
|
||||
been recalled.'''
|
||||
if enabled, and a 'remove draft' button if the current form is a draft
|
||||
that has been recalled.'''
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<div id="tracking-code">')
|
||||
r += htmltext('<h3>%s</h3>') % _('Tracking code')
|
||||
if self.formdef.enable_tracking_codes:
|
||||
r += htmltext('<div class="tracking-code-part">')
|
||||
r += htmltext('<h3>%s</h3>') % _('Tracking code')
|
||||
|
||||
tracking_code = None
|
||||
draft_formdata_id = data.get('draft_formdata_id')
|
||||
if draft_formdata_id:
|
||||
formdata = self.formdef.data_class().get(draft_formdata_id)
|
||||
tracking_code = formdata.tracking_code
|
||||
else:
|
||||
tracking_code = data.get('future_tracking_code')
|
||||
tracking_code = None
|
||||
draft_formdata_id = data.get('draft_formdata_id')
|
||||
if draft_formdata_id:
|
||||
formdata = self.formdef.data_class().get(draft_formdata_id)
|
||||
tracking_code = formdata.tracking_code
|
||||
else:
|
||||
tracking_code = data.get('future_tracking_code')
|
||||
|
||||
if tracking_code:
|
||||
get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'popup.js'])
|
||||
r += htmltext('<a rel="popup" href="%s">%s</a>') % (
|
||||
'code/%s/' % tracking_code, tracking_code)
|
||||
r += TextsDirectory.get_html_text('tracking-code-short-text')
|
||||
if tracking_code:
|
||||
get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'popup.js'])
|
||||
r += htmltext('<a rel="popup" href="%s">%s</a>') % (
|
||||
'code/%s/' % tracking_code, tracking_code)
|
||||
r += TextsDirectory.get_html_text('tracking-code-short-text')
|
||||
r += htmltext('</div>') # <!-- .tracking-code-part -->
|
||||
|
||||
if data.get('is_recalled_draft'):
|
||||
r += htmltext('<form action="removedraft" method="POST">')
|
||||
r += htmltext('<input type="hidden" name="magictoken" value="%s">') % magictoken
|
||||
r += htmltext('<button>%s</button>') % _('Remove Draft')
|
||||
r += htmltext('</form>')
|
||||
r += htmltext('</div>') # <!-- #tracking-code -->
|
||||
return r.getvalue()
|
||||
|
||||
text = r.getvalue()
|
||||
if not text:
|
||||
return ''
|
||||
|
||||
return htmltext('<div id="tracking-code">') + text + htmltext('</div>')
|
||||
|
||||
def get_transient_formdata(self, magictoken=Ellipsis):
|
||||
if magictoken is Ellipsis:
|
||||
|
@ -559,7 +573,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
# [session_var_id] is available on the first page.
|
||||
session.force()
|
||||
|
||||
if self.formdef.enable_tracking_codes:
|
||||
if self.has_draft_support():
|
||||
if get_request().form.get('_ajax_form_token'):
|
||||
# _ajax_form_token is immediately removed, this prevents
|
||||
# late autosave() to overwrite data after the user went to a
|
||||
|
@ -592,7 +606,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
# first hit on first page, if tracking code are enabled and we
|
||||
# are not editing an existing formdata, generate a new tracking
|
||||
# code.
|
||||
if not self.edit_mode and self.formdef.enable_tracking_codes and not get_request().form.has_key('mt'):
|
||||
if not self.edit_mode and self.has_draft_support() and not get_request().form.has_key('mt'):
|
||||
tracking_code = get_publisher().tracking_code_class()
|
||||
tracking_code.store()
|
||||
token = randbytes(8)
|
||||
|
@ -622,7 +636,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
form.add_hidden('magictoken', '-1')
|
||||
form.add_submit('cancel')
|
||||
|
||||
if self.formdef.enable_tracking_codes:
|
||||
if self.has_draft_support():
|
||||
form.add_submit('removedraft')
|
||||
form.add_submit('savedraft')
|
||||
|
||||
|
@ -723,21 +737,21 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
displayed_fields=submitted_fields,
|
||||
transient_formdata=transient_formdata)
|
||||
form.add_submit('previous')
|
||||
if self.formdef.enable_tracking_codes:
|
||||
if self.has_draft_support():
|
||||
form.add_submit('removedraft')
|
||||
form.add_submit('savedraft')
|
||||
form.add_submit('submit')
|
||||
if page_no > 0 and form.get_submit() == 'previous':
|
||||
return self.previous_page(page_no, magictoken)
|
||||
|
||||
if self.formdef.enable_tracking_codes and form.get_submit() == 'removedraft':
|
||||
if self.has_draft_support() and form.get_submit() == 'removedraft':
|
||||
return self.removedraft()
|
||||
|
||||
form_data = session.get_by_magictoken(magictoken, {})
|
||||
data = self.formdef.get_data(form)
|
||||
form_data.update(data)
|
||||
|
||||
if self.formdef.enable_tracking_codes and form.get_submit() == 'savedraft':
|
||||
if self.has_draft_support() and form.get_submit() == 'savedraft':
|
||||
filled = self.save_draft(form_data, page_no)
|
||||
return redirect(filled.get_url().rstrip('/'))
|
||||
|
||||
|
@ -796,8 +810,8 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
get_session().message = ('error', _('This form has already been submitted.'))
|
||||
return redirect(get_publisher().get_backoffice_url() + '/submission/')
|
||||
return template.error_page(_('This form has already been submitted.'))
|
||||
elif self.formdef.enable_tracking_codes and not self.edit_mode:
|
||||
# if there's no draft yet and tracking codes are enabled, create one
|
||||
elif self.has_draft_support():
|
||||
# if there's no draft yet and drafts are supported, create one
|
||||
filled = self.save_draft(form_data, page_no)
|
||||
|
||||
# the page has been successfully submitted, maybe new pages
|
||||
|
@ -828,7 +842,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
form.add_hidden('page', '-1')
|
||||
form.add_hidden('magictoken', '-1')
|
||||
form.add_submit('cancel')
|
||||
if self.formdef.enable_tracking_codes:
|
||||
if self.has_draft_support():
|
||||
form.add_submit('removedraft')
|
||||
form.add_submit('savedraft')
|
||||
|
||||
|
@ -863,10 +877,10 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
if form.get_submit() == 'previous':
|
||||
return self.previous_page(len(self.pages), magictoken)
|
||||
|
||||
if self.formdef.enable_tracking_codes and form.get_submit() == 'removedraft':
|
||||
if self.has_draft_support() and form.get_submit() == 'removedraft':
|
||||
return self.removedraft()
|
||||
|
||||
if self.formdef.enable_tracking_codes and form.get_submit() == 'savedraft':
|
||||
if self.has_draft_support() and form.get_submit() == 'savedraft':
|
||||
filled = self.save_draft(form_data, page_no = -1)
|
||||
return redirect(filled.get_url().rstrip('/'))
|
||||
|
||||
|
@ -1114,7 +1128,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
return redirect(url)
|
||||
|
||||
def set_tracking_code(self, formdata, magictoken_data=None):
|
||||
if not self.formdef.enable_tracking_codes:
|
||||
if not self.has_draft_support():
|
||||
return
|
||||
if formdata.tracking_code:
|
||||
return
|
||||
|
@ -1185,7 +1199,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
form.add_submit('previous', _('Previous'))
|
||||
form.add_submit('cancel', _('Cancel'), css_class = 'cancel')
|
||||
session = get_session()
|
||||
if self.formdef.enable_tracking_codes:
|
||||
if self.has_draft_support():
|
||||
form.add_submit('savedraft', _('Save Draft'), css_class = 'save-draft',
|
||||
attrs={'style': 'display: none'})
|
||||
form.add_hidden('step', '2')
|
||||
|
@ -1199,7 +1213,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
magictoken=magictoken),
|
||||
'steps': lambda: self.step(1, None),
|
||||
}
|
||||
if self.formdef.enable_tracking_codes and data:
|
||||
if self.has_draft_support() and data:
|
||||
context['tracking_code_box'] = lambda: self.tracking_code_box(data, magictoken)
|
||||
|
||||
return template.QommonTemplateResponse(
|
||||
|
@ -1234,7 +1248,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
return redirect(get_publisher().get_backoffice_url() + '/submission/')
|
||||
return PublicFormStatusPage(self.formdef, filled)
|
||||
|
||||
if not (get_request().is_in_backoffice() or filled.formdef.enable_tracking_codes):
|
||||
if not (get_request().is_in_backoffice() or self.has_draft_support()):
|
||||
# don't allow restoring drafts if drafts are no longer enabled for
|
||||
# this form.
|
||||
raise errors.AccessForbiddenError()
|
||||
|
|
|
@ -195,6 +195,12 @@ class Session(QommonSession, CaptchaSession, StorableObject):
|
|||
except OSError:
|
||||
pass
|
||||
|
||||
def has_user(self):
|
||||
user_id = QuixoteSession.get_user(self)
|
||||
if user_id and not str(user_id).startswith('anonymous-'):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_user(self):
|
||||
user_id = QuixoteSession.get_user(self)
|
||||
if user_id:
|
||||
|
|
Loading…
Reference in New Issue