def _handleSave(self, action, msg='Saved form data'): self.save_attempt = True data, errors = self.extractData() if errors or IFormDefinition.providedBy(self.context) or self.saved: return False # just validate if errors, or if context if defn if not self.saved: result = {} # submitted data. k: group name; v: dict of name/value group_keys = [] for group in self.groups: groupdata = {} form_group_data = group.extractData()[0] for name, _field in group.fields.items(): group_keys.append(name) fieldname = _field.field.__name__ default = getattr(_field.field, 'default', None) field_data = form_group_data.get(name, default) if ICollection.providedBy(_field.field): if isinstance(_field.field.value_type, DictRow): is_nonempty_row = lambda v: any(v.values()) field_data = filter(is_nonempty_row, field_data) groupdata[fieldname] = field_data result[group.__name__] = groupdata # filter default fieldset values, ignore group values in data dict: result[''] = dict([(k, v) for k, v in data.items() if k not in group_keys]) self._saveResult(result) self.saved = True history_log(self.context, message=msg, set_modified=True) notify(ObjectModifiedEvent(self.context)) transaction.get().note(msg) self._status.addStatusMessage('Saved form data', type='info') return True
def sync_simple_form(form, components): """ Sync form data storage objects with schema of form definition components. """ for name in components.names: group = components.groups[name] schema = group.schema if group.group_usage == u'grid': schema = grid_wrapper_schema(group.schema) if name not in form.data: form.data[name] = FormEntry() # add new form.data[name].sign(schema) history_log(form, 'Schema updated for form entries.')
def update(self, *args, **kwargs): if not kwargs.get('saveonly', False): self._init_baseform() msg = '' if 'payload' in self.request.form: json = self.request.form.get('payload').strip() if json: oldkeys = self.context.keys() # save the data payload to records, also notifies # ObjectModifiedEvent, if data is modified, which # will result in reindexing embedded catalog used # by measures: self.context.update_all(json) newkeys = self.context.keys() count_new = len(set(newkeys) - set(oldkeys)) count_updated = len(set(oldkeys) & set(newkeys)) count_removed = len(set(oldkeys) - set(newkeys)) msg = 'Data has been saved. ' if count_new or count_updated or count_removed: msg += '(' if count_new: msg += ' %s new entries. ' % count_new if count_updated: msg += ' %s updated entries. ' % ( count_updated,) if count_removed: msg += ' %s removed entries. ' % ( count_removed,) if count_new or count_updated or count_removed: msg += ')' history_log(self.context, msg) if 'save_submit' in self.request.form: wftool = getToolByName(self.context, 'portal_workflow') chain = wftool.getChainFor(self.context)[0] state = wftool.getStatusOf(chain, self.context)['review_state'] if state == 'visible': wftool.doActionFor(self.context, 'submit') self.context.reindexObject() msg += ' (form submitted for review)' if not kwargs.get('saveonly', False): url = self.context.absolute_url() self.request.RESPONSE.redirect(url) if self.has_metadata: self.mdform.update() md_msg = 'Saved metadata fields on multi-record form.' self.mdform._handleSave(None, msg=md_msg) if msg: self._status.addStatusMessage(msg, type='info')
def update(self, *args, **kwargs): if not kwargs.get('saveonly', False): self._init_baseform() msg = '' if 'payload' in self.request.form: # strip out double-escaping of unicode (ugly): json = self.request.form.get('payload').strip() if json: json = unicode_unwrap(json) oldkeys = self.context.keys() # save the data payload to records, also notifies # ObjectModifiedEvent, if data is modified, which # will result in reindexing embedded catalog used # by measures: self.context.update_all(json) newkeys = self.context.keys() count_new = len(set(newkeys) - set(oldkeys)) count_updated = len(set(oldkeys) & set(newkeys)) count_removed = len(set(oldkeys) - set(newkeys)) msg = 'Data has been saved. ' if count_new or count_updated or count_removed: msg += '(' if count_new: msg += ' %s new entries. ' % count_new if count_updated: msg += ' %s updated entries. ' % (count_updated, ) if count_removed: msg += ' %s removed entries. ' % (count_removed, ) if count_new or count_updated or count_removed: msg += ')' history_log(self.context, msg) if 'save_submit' in self.request.form: wftool = getToolByName(self.context, 'portal_workflow') chain = wftool.getChainFor(self.context)[0] state = wftool.getStatusOf(chain, self.context)['review_state'] if state == 'visible': wftool.doActionFor(self.context, 'submit') self.context.reindexObject() msg += ' (form submitted for review)' if not kwargs.get('saveonly', False): url = self.context.absolute_url() self.request.RESPONSE.redirect(url) if self.has_metadata: self.mdform.update() md_msg = 'Saved metadata fields on multi-record form.' self.mdform._handleSave(None, msg=md_msg) if msg: self._status.addStatusMessage(msg, type='info')
def handle_measure_modify(context, event): # set modification time and a history log message: msg = "Updated modification timestamp, which invalidates stale " "cached queries, datapoints." history_log(context, message=msg, set_modified=True) # Invalidate IComposedQuery adapter lookups for measure for # both numerator and denominator: context._v_q_numerator = None context._v_q_denominator = None # invalidate cache of built repoze.catalog query: context._v_query_numerator = None context._v_query_denominator = None # ensure that all connections, instances, threads have fresh objects, # with no stale _v_ prefixed volatile attributes -- invalidates the # measure for all ZODB connections: context._p_changed = True # invalidate all cached data points to which the measure is relevant: DataPointCache().reload(IUUID(context))
def handle_measure_modify(context, event): # set modification time and a history log message: msg = 'Updated modification timestamp, which invalidates stale '\ 'cached queries, datapoints.' history_log(context, message=msg, set_modified=True) # Invalidate IComposedQuery adapter lookups for measure for # both numerator and denominator: context._v_q_numerator = None context._v_q_denominator = None # invalidate cache of built repoze.catalog query: context._v_query_numerator = None context._v_query_denominator = None # ensure that all connections, instances, threads have fresh objects, # with no stale _v_ prefixed volatile attributes -- invalidates the # measure for all ZODB connections: context._p_changed = True # invalidate all cached data points to which the measure is relevant: DataPointCache().reload(IUUID(context))
def sync_multi_form(form, definition): """ Update all contained form entry records, signed with definition schema. """ modified = False for entry in form.values(): oldsig = entry.signature entry.sign(definition.schema) if oldsig != entry.signature: modified = True if modified: history_log(form, 'Schema updated for form entries.') # notify items may be effected by schema change, warranting a # re-index of embedded catalog and reload of cached data-points: notify( ObjectModifiedEvent(form, Attributes(IRecordContainer, 'items')) )
def _update(self, *args, **kwargs): req = self.request prefix = 'payload-query-' payload_keys = [k for k in self.request.form if k.startswith(prefix)] if not payload_keys: return _info = lambda name: (name.replace(prefix, ''), req.get(name)) payloads = map(_info, payload_keys) log_messages = [] for name, payload in payloads: composed = self.composed_query(name) if not composed: raise ValueError('unknown query name') adapter = ComposedQueryJSONAdapter(composed, self.schema) adapter.update(str(payload)) msg = u'Updated query criteria for %s' % name self.status.addStatusMessage(msg, type='info') log_messages.append(msg) history_log( self.context, message='\n'.join(log_messages), set_modified=True, ) return True # updated