1.1 --- a/MoinForms.py Sat Feb 09 19:50:37 2013 +0100
1.2 +++ b/MoinForms.py Sat Feb 09 19:55:38 2013 +0100
1.3 @@ -29,9 +29,16 @@
1.4 self.pagename = pagename
1.5 self.request = request
1.6 self.access_handler = None
1.7 + self.attributes = None
1.8
1.9 - def getAccessHandler(self, attributes):
1.10 - return FormAccess(self.pagename, self.request, attributes)
1.11 + def getAccessHandler(self):
1.12 +
1.13 + """
1.14 + Return an access handler for the form whose attributes have been
1.15 + obtained and stored in this instance.
1.16 + """
1.17 +
1.18 + return FormAccess(self.pagename, self.request, self.attributes)
1.19
1.20 def processForm(self):
1.21
1.22 @@ -47,35 +54,54 @@
1.23 form = get_form(self.request)
1.24 fields = getFields(form, remove=True)
1.25
1.26 - # Modify and validate the form.
1.27 -
1.28 - self.modifyFields(fields)
1.29 -
1.30 - # Get the form definition.
1.31 + # Detect any request to load data.
1.32
1.33 - attributes, text = self.getFormForFragment(fields)
1.34 - structure = getFormStructure(text, self.request)
1.35 - self.access_handler = self.getAccessHandler(attributes)
1.36 + if fields.has_key("load"):
1.37 + try:
1.38 + number = int(fields["load"][0])
1.39 + except ValueError:
1.40 + fields = {}
1.41 + else:
1.42 + self.attributes, text = self.getFormForFragment(fields)
1.43 + self.access_handler = self.getAccessHandler()
1.44 + fields = self.loadFields(number)
1.45
1.46 - # Check the permissions on the form.
1.47 + self.unfinished(fields, form)
1.48 +
1.49 + # Otherwise, process any supplied data.
1.50 +
1.51 + else:
1.52 + # Modify and validate the form.
1.53 +
1.54 + self.modifyFields(fields)
1.55 +
1.56 + # Get the form definition.
1.57
1.58 - if not self.checkPermissions("write"):
1.59 - self.request.theme.add_msg(_("You do not appear to have access to this form."), "error")
1.60 - do_show(self.pagename, self.request)
1.61 - return
1.62 + self.attributes, text = self.getFormForFragment(fields)
1.63 + self.access_handler = self.getAccessHandler()
1.64 + structure = getFormStructure(text, self.request)
1.65 +
1.66 + # Check the permissions on the form.
1.67
1.68 - # Without any form definition, the page is probably the wrong one.
1.69 + if not self.checkPermissions("write"):
1.70 + self.request.theme.add_msg(_("You do not appear to have access to this form."), "error")
1.71 + do_show(self.pagename, self.request)
1.72 + return
1.73 +
1.74 + # Without any form definition, the page is probably the wrong one.
1.75
1.76 - if not structure:
1.77 - self.request.theme.add_msg(_("This page does not provide a form."), "error")
1.78 - do_show(self.pagename, self.request)
1.79 - return
1.80 + if not structure:
1.81 + self.request.theme.add_msg(_("This page does not provide a form."), "error")
1.82 + do_show(self.pagename, self.request)
1.83 + return
1.84
1.85 - # With a form definition, attempt to validate the fields.
1.86 + # With a form definition, attempt to validate the fields.
1.87
1.88 - if self.validateFields(fields, structure):
1.89 - self.finished(fields, form)
1.90 - else:
1.91 + if self.validateFields(fields, structure):
1.92 + if self.shouldFinish(fields):
1.93 + self.finished(fields, form)
1.94 + return
1.95 +
1.96 self.unfinished(fields, form)
1.97
1.98 def finished(self, fields, form):
1.99 @@ -94,6 +120,23 @@
1.100 self.serialiseFields(fields, form)
1.101 do_show(self.pagename, self.request)
1.102
1.103 + def shouldFinish(self, fields):
1.104 +
1.105 + """
1.106 + Subject to the attributes stored for the form in this instance, return
1.107 + whether any field referenced by the "finishing" attribute is present
1.108 + and thus indicate whether the form handling should finish.
1.109 + """
1.110 +
1.111 + finishing = self.attributes.has_key("finishing") and self.attributes["finishing"].split(",")
1.112 +
1.113 + if finishing:
1.114 + for name in finishing:
1.115 + if fields.has_key(name):
1.116 + return True
1.117 +
1.118 + return False
1.119 +
1.120 def getFormForFragment(self, fields):
1.121
1.122 "Return the attributes and text of the form being handled."
1.123 @@ -249,10 +292,7 @@
1.124
1.125 def storeFields(self, fields):
1.126
1.127 - """
1.128 - Store the given 'fields' as a Python object representation, subject to
1.129 - the given 'attributes'.
1.130 - """
1.131 + "Store the given 'fields' as a Python object representation."
1.132
1.133 store = FormStore(self.access_handler)
1.134 store.append(repr(fields))
1.135 @@ -264,18 +304,6 @@
1.136 store = FormStore(self.access_handler)
1.137 return loadFields(store, number)
1.138
1.139 -def loadFieldsForRequest(number, attrs, request):
1.140 -
1.141 - """
1.142 - Load the fields corresponding to the given record 'number', using the form
1.143 - 'attrs' to control access to the form data, and using the 'request' for
1.144 - access and retrieval purposes.
1.145 - """
1.146 -
1.147 - access_handler = FormAccess(request.page.page_name, request, attrs)
1.148 - store = FormStore(access_handler)
1.149 - return loadFields(store, number)
1.150 -
1.151 def loadFields(store, number):
1.152
1.153 """
1.154 @@ -460,7 +488,7 @@
1.155
1.156 # Common formatting functions.
1.157
1.158 -def getFormOutput(text, fields, path=None, fragment=None, repeating=None, index=None):
1.159 +def getFormOutput(text, fields, form_fragment=None, path=None, fragment=None, repeating=None, index=None):
1.160
1.161 """
1.162 Combine regions found in the given 'text' and then return them as a single
1.163 @@ -472,16 +500,22 @@
1.164 The given 'fields' are used to populate fields provided in forms and to
1.165 control whether sections are populated or not.
1.166
1.167 + The optional 'form_fragment' is used to indicate the form to which the
1.168 + fields belong.
1.169 +
1.170 The optional 'path' is used to adjust form fields to refer to the correct
1.171 part of the form hierarchy.
1.172
1.173 - The optional 'fragment' is used to indicate the form to which the fields
1.174 - belong.
1.175 + The optional 'fragment' is used to indicate the form being output. If this
1.176 + value is different to 'form_fragment', the structure of the form should not
1.177 + be influenced by the 'fields'.
1.178
1.179 The optional 'repeating' and 'index' is used to refer to individual values
1.180 of a designated field.
1.181 """
1.182
1.183 + this_form = fragment and form_fragment == fragment or not fragment and not form_fragment
1.184 +
1.185 output = []
1.186 section = fields
1.187
1.188 @@ -501,9 +535,14 @@
1.189 message_name = attributes.get("message")
1.190 absent_message_name = attributes.get("not-message")
1.191
1.192 + # Ignore sections not related to the supplied field data.
1.193 +
1.194 + if not this_form:
1.195 + pass
1.196 +
1.197 # Sections are groups of fields in their own namespace.
1.198
1.199 - if section_name and section.has_key(section_name):
1.200 + elif section_name and section.has_key(section_name):
1.201
1.202 # Iterate over the section contents ignoring the given indexes.
1.203
1.204 @@ -512,7 +551,7 @@
1.205
1.206 # Get the output for the section.
1.207
1.208 - output.append(getFormOutput(body, element,
1.209 + output.append(getFormOutput(body, element, form_fragment,
1.210 path and ("%s/%s" % (path, element_ref)) or element_ref, fragment))
1.211
1.212 # Message regions are conditional on a particular field and
1.213 @@ -522,21 +561,21 @@
1.214
1.215 if attributes.get("repeating"):
1.216 for index in range(0, len(section[message_name])):
1.217 - output.append(getFormOutput(body, section, path, fragment, message_name, index))
1.218 + output.append(getFormOutput(body, section, form_fragment, path, fragment, message_name, index))
1.219 else:
1.220 - output.append(getFormOutput(body, section, path, fragment))
1.221 + output.append(getFormOutput(body, section, form_fragment, path, fragment))
1.222
1.223 # Not-message regions are conditional on a particular field being
1.224 # absent. They reference the current namespace.
1.225
1.226 elif absent_message_name and not section.has_key(absent_message_name):
1.227 - output.append(getFormOutput(body, section, path, fragment))
1.228 + output.append(getFormOutput(body, section, form_fragment, path, fragment))
1.229
1.230 # Inspect and include other regions.
1.231
1.232 else:
1.233 output.append(header)
1.234 - output.append(getFormOutput(body, section, path, fragment, repeating, index))
1.235 + output.append(getFormOutput(body, section, form_fragment, path, fragment, repeating, index))
1.236 output.append(close)
1.237
1.238 return "".join(output)
1.239 @@ -837,7 +876,9 @@
1.240 write = write or request.write
1.241 page = request.page
1.242
1.243 - fields = getFields(get_form(request))
1.244 + form = get_form(request)
1.245 + form_fragment = form.get("fragment", [None])[0]
1.246 + fields = getFields(form)
1.247
1.248 # Prepare the query string for the form action URL.
1.249
1.250 @@ -861,7 +902,7 @@
1.251 # Obtain page text for the form, incorporating subregions and applicable
1.252 # sections.
1.253
1.254 - output = getFormOutput(text, fields, fragment=fragment)
1.255 + output = getFormOutput(text, fields, form_fragment=form_fragment, fragment=fragment)
1.256 write(formatText(output, request, fmt, inhibit_p=False))
1.257
1.258 write(fmt.rawHTML('</form>'))