def _base_args(self): """Method which will calculate _base class arguments. """ args = super(PatternWidget, self)._base_args() args['name'] = self.name args['value'] = self.value if (IAddForm.providedBy(self.form) and self.form.portal_type == 'uu.taskplanner') or \ (not IAddForm.providedBy(self.form) and ITaskPlanner.providedBy(self.context) and 'pattern_options' in args): args['pattern_options']['date'] = False return args
def viewType(context, request): """Determine what type of view the user is looking at. This returns one of three options: ``view`` for normal object views, ``add`` for add forms, ``edit`` for edit forms, and ``other`` for all other types.""" view = request.other.get("PUBLISHED") if view is not None: if IAddForm.providedBy(view): return "add" if IEditForm.providedBy(view): return "edit" for url in ["ACTUAL_URL", "VIRTUAL_URL", "URL"]: current_url = request.get(url) if current_url is not None: break else: return "view" if current_url.endswith("/"): current_url = current_url[:-1] if current_url.endswith("@@edit"): return "edit" elif "/++add++" in current_url: return "add" if current_url == aq_inner(context).absolute_url(): return "view" return "other"
def __getitem__(self, key, silent=False): """ Allows us to get field values from the template. For example using either view/title or view['title'] Enables us to have one form for both add/edit """ if IAddForm.providedBy(self): return self.request.get(key, None) if key == 'macros': return self.index.macros if key in self.request: return self.request.get(key) context = aq_inner(self.context) if hasattr(self.context, key): return getattr(context, key) elif shasattr(context, 'Schema'): field = context.Schema().get(key) if field is not None: return field.get(context) if not silent: raise KeyError('Could not get key %s in the request or context' % key)
def page_title(self): ''' Get the page title. If we are in the portal_factory we want use the "Add $FTI_TITLE" form (see #12117). NOTE: other implementative options can be: - to use "Untitled" instead of "Add" or - to check the isTemporary method of the edit view instead of the creation_flag ''' if (hasattr(aq_base(self.context), 'isTemporary') and self.context.isTemporary()): # if we are in the portal_factory we want the page title to be # "Add fti title" portal_types = getToolByName(self.context, 'portal_types') fti = portal_types.getTypeInfo(self.context) return translate('heading_add_item', domain='plone', mapping={'itemtype': fti.Title()}, context=self.request, default='New ${itemtype}') if IAddForm.providedBy(self.view): portal_types = getToolByName(self.context, 'portal_types') fti = portal_types.getTypeInfo(self.view.portal_type) return translate('heading_add_item', domain='plone', mapping={'itemtype': fti.Title()}, context=self.request, default='New ${itemtype}') title = getattr(self.view, 'title', None) if not title: context_state = getMultiAdapter((self.context, self.request), name=u'plone_context_state') title = context_state.object_title() return escape(safe_unicode(title))
def viewType(context, request): """Determine what type of view the user is looking at. This returns one of three options: ``view`` for normal object views, ``add`` for add forms, ``edit`` for edit forms, and ``other`` for all other types.""" view=request.other.get("PUBLISHED") if view is not None: if IAddForm.providedBy(view): return "add" if IEditForm.providedBy(view): return "edit" for url in [ "ACTUAL_URL", "VIRTUAL_URL", "URL" ]: current_url=request.get(url) if current_url is not None: break else: return "view" if current_url.endswith("/"): current_url=current_url[:-1] if current_url.endswith("@@edit"): return "edit" elif "/++add++" in current_url: return "add" if current_url==aq_inner(context).absolute_url(): return "view" return "other"
def update(self): isForm = IEditForm.providedBy(self.form) or IAddForm.providedBy(self.form) if not isForm: return if not hasattr(self.form, 'portal_type'): return if self.form.portal_type == 'organization': self.remove('logo') self.remove('activity') self.remove('IContactDetails.im_handle') self.remove('IContactDetails.country') self.remove('IContactDetails.cell_phone') self.remove('IContactDetails.fax') self.remove('IContactDetails.region') sm = getSecurityManager() if not sm.checkPermission('RIC: Administer website', self.context): self.form.fields['IBasic.title'].mode = 'display' self.form.fields['organization_type'].mode = 'display' contactFields = self.form.groups[0].fields #contactFields['IContactDetails.email'].field.required = True elif self.form.portal_type == 'person': self.remove('gender') self.remove('person_title') self.remove('photo') self.remove('IContactDetails.im_handle') self.remove('IContactDetails.fax') self.remove('IContactDetails.country') self.remove('IContactDetails.region') self.remove('IContactDetails.website') self.form.fields['firstname'].field.required = True contactFields = self.form.groups[0].fields contactFields['IContactDetails.email'].field.required = True
def autosave(event): context = getattr(event, 'object', None) request = getattr(context, 'REQUEST', getRequest()) if not request.URL.endswith('/@@z3cform_validate_field'): return draft = getCurrentDraft(request) if draft is None: return view = getattr(request, 'PUBLISHED', None) form = getattr(view, 'context', None) if hasattr(aq_base(form), 'form_instance'): form = form.form_instance if IAddForm.providedBy(form): target = getattr(draft, '_draftAddFormTarget', None) if not target: return target = target.__of__(context) else: target = context fti = queryUtility(IDexterityFTI, name=target.portal_type) if IDraftable.__identifier__ not in fti.behaviors: return if not hasattr(form, "extractData"): return data, errors = form.extractData() if not errors: content = DraftProxy(draft, target) # Drop known non-draftable values map(data.pop, [key for key in AUTOSAVE_BLACKLIST if key in data]) # Values are applied within savepoint to allow revert of any # unexpected side-effects from setting field values sp = transaction.savepoint(optimistic=True) try: applyChanges(form, content, data) for group in getattr(form, 'groups', []): applyChanges(group, content, data) except Exception: # If shortname was not blacklisted, it could fail because the # behavior trying to rename object on add form. pass values = dict(draft.__dict__) sp.rollback() for key, value in values.items(): setattr(draft, key, value) # Disable Plone 5 implicit CSRF to update draft if HAS_PLONE_PROTECT: alsoProvides(request, IDisableCSRFProtection)
def update(self): super(ReferenceNumberWidget, self).update() self.mode = 'display' #check if is a add- or a editForm if IAddForm.providedBy(self.form.parentForm): self.value = _(u'label_no_reference_number', default="Reference Number will be generated \ after content creation") else: self.value = IReferenceNumber(self.context).get_number()
def validate(self, value): # setting parent, for that we check if there are a Add- or a Editform super(ReferenceNumberPrefixValidator, self).validate(value) if IAddForm.providedBy(self.view.parentForm): if not PrefixAdapter(self.context).is_valid_number(value): raise schema.interfaces.ConstraintNotSatisfied() else: parent = aq_parent(aq_inner(self.context)) if not PrefixAdapter(parent).is_valid_number(value, self.context): raise schema.interfaces.ConstraintNotSatisfied()
def update(self): super(ReferenceNumberWidget, self).update() # check if is a add- or a editForm if IAddForm.providedBy(self.form.parentForm): self.value = _( u'label_no_reference_number', default="Reference Number will be generated \ after content creation") else: self.value = IReferenceNumber(self.context).get_number()
def validate(self, value): """ Don't validate when adding a country manager or sector. They'll get a default password (see default_password below) and then an email with link to set their password themselves. Refs: #10284 """ if IAddForm.providedBy(self.view) and \ self.view.portal_type in \ ['euphorie.countrymanager', 'euphorie.sector']: return return super(PasswordValidator, self).validate(value)
def get_context_url(context): if IAddForm.providedBy(context): # Use the request URL if we are looking at an addform url = context.request.get('URL') elif hasattr(context, 'absolute_url'): url = context.absolute_url if callable(url): url = url() else: url = get_portal_url(context) return url
def _base_args(self): """Method which will calculate _base class arguments. Returns (as python dictionary): - `pattern`: pattern name - `pattern_options`: pattern options - `name`: field name - `value`: field value :returns: Arguments which will be passed to _base :rtype: dict """ args = super(AjaxSelectWidget, self)._base_args() args["name"] = self.name args["value"] = self.value args.setdefault("pattern_options", {}) field_name = self.field and self.field.__name__ or None context = self.context # We need special handling for AddForms if IAddForm.providedBy(getattr(self, "form")): context = self.form vocabulary_name = self.vocabulary field = None if IChoice.providedBy(self.field): args["pattern_options"]["maximumSelectionSize"] = 1 field = self.field elif ICollection.providedBy(self.field): field = self.field.value_type if not vocabulary_name and field is not None: vocabulary_name = field.vocabularyName args["pattern_options"] = dict_merge( get_ajaxselect_options( context, args["value"], self.separator, vocabulary_name, self.vocabulary_view, field_name ), args["pattern_options"], ) if field and getattr(field, "vocabulary", None): form_url = self.request.getURL() source_url = "%s/++widget++%s/@@getSource" % (form_url, self.name) args["pattern_options"]["vocabularyUrl"] = source_url # ISequence represents an orderable collection if ISequence.providedBy(self.field) or self.orderable: args["pattern_options"]["orderable"] = True return args
def _base_args(self): """Method which will calculate _base class arguments. Returns (as python dictionary): - `pattern`: pattern name - `pattern_options`: pattern options - `name`: field name - `value`: field value :returns: Arguments which will be passed to _base :rtype: dict """ args = super(AjaxSelectWidget, self)._base_args() args['name'] = self.name args['value'] = self.value args.setdefault('pattern_options', {}) field_name = self.field and self.field.__name__ or None context = self.context # We need special handling for AddForms if IAddForm.providedBy(getattr(self, 'form')): context = self.form vocabulary_name = self.vocabulary field = None if IChoice.providedBy(self.field): args['pattern_options']['maximumSelectionSize'] = 1 field = self.field elif ICollection.providedBy(self.field): field = self.field.value_type if not vocabulary_name and field is not None: vocabulary_name = field.vocabularyName args['pattern_options'] = dict_merge( get_ajaxselect_options(context, args['value'], self.separator, vocabulary_name, self.vocabulary_view, field_name), args['pattern_options']) if field and getattr(field, 'vocabulary', None): form_url = self.request.getURL() source_url = "%s/++widget++%s/@@getSource" % (form_url, self.name) args['pattern_options']['vocabularyUrl'] = source_url # ISequence represents an orderable collection if ISequence.providedBy(self.field) or self.orderable: args['pattern_options']['orderable'] = True return args
def obtainType(self): # noqa """ Obtains the type of the context object or of the object we are adding """ if 'type' in self.request.form: return self.request.form['type'] elif IAddForm.providedBy(getattr(self.form, '__parent__', None)): return getattr(getattr( self.form, '__parent__', self.form), 'portal_type', None) else: if hasattr(self.context, 'portal_type'): return self.context.portal_type return None
def obtainType(self): # noqa """ Obtains the type of the context object or of the object we are adding """ if 'type' in self.request.form: return self.request.form['type'] elif IAddForm.providedBy(getattr(self.form, '__parent__', None)): return getattr(getattr(self.form, '__parent__', self.form), 'portal_type', None) else: if hasattr(self.context, 'portal_type'): return self.context.portal_type return None
def _base_args(self): """Method which will calculate _base class arguments. Returns (as python dictionary): - `pattern`: pattern name - `pattern_options`: pattern options - `name`: field name - `multiple `: field multiple :returns: Arguments which will be passed to _base :rtype: dict """ args = super(FileUploadWidget, self)._base_args() url = '%s/++widget++%s/@@upload/' % ( self.request.getURL(), self.name) args['name'] = self.name args['multiple'] = self.multiple args.setdefault('pattern_options', {}) args['pattern_options'] = {'url': url} self.cleanup() loaded = [] if not IAddForm.providedBy(self.form): dm = queryMultiAdapter((self.context, self.field,), IDataManager) else: dm = None current_field_value = ( dm.query() if ((dm is not None) and self.field.interface.providedBy(self.context)) else None ) if current_field_value and current_field_value != NO_VALUE: if not isinstance(current_field_value, list): current_field_value = [current_field_value] current_field_set = set(current_field_value) for item in current_field_set: dl_url = '%s/++widget++%s/@@downloadexisting/' % ( self.request.getURL(), self.name) + item.filename info = {'name': item.filename, 'title': item.filename, 'size': item.getSize(), 'url': dl_url, } loaded.append(info) args['pattern_options']['existing'] = loaded return args
def save(event): if not IDrafting.providedBy(event.action.request): return if event.action.name != 'form.buttons.save': return data, errors = event.action.form.extractData() if errors: return if IAddForm.providedBy(event.action.form): draft = getCurrentDraft(event.action.form.request) target = getattr(draft, '_draftAddFormTarget') if target: syncDraftOnSave(target, event) else: syncDraftOnSave(event.action.form.context, event)
def save(event): if not IDrafting.providedBy(event.action.request): return if event.action.name != 'form.buttons.save': return data, errors = event.action.form.extractData() if errors: return if IAddForm.providedBy(event.action.form): draft = getCurrentDraft(event.action.form.request) target = getattr(draft, '_draftAddFormTarget', None) if target: syncDraftOnSave(target, event) else: discardDraftsOnCancel(event.action.form.context, event) else: syncDraftOnSave(event.action.form.context, event)
def update(self): form = self.__parent__ if IFormWrapper.providedBy(form): form = form.form_instance if not IAddForm.providedBy(form): return uuid = self.request.form.get('translation') language = self.request.form.get('language') if not uuid or not language: return obj = getObjectByuuid(self.context, uuid) context_state = getMultiAdapter( (obj, self.request), name=u"plone_context_state" ) # This is now the parent of the item that we're trying to # create a new translation for! obj = context_state.parent() # If it's the site root, then we're done. if IPloneSiteRoot.providedBy(obj): return # Now we just need to check if the parent has already been # translated into the required language in which case we're # also done. translations = ITranslationGraph(obj).getTranslations() if language in dict(translations): return # Okay, we'll show the notice. self.available = True self.folder = obj self.language = self.request.locale.displayNames.languages.\ get(language)
def toFieldValue(self, value): """Converts the value to a storable form.""" context = self.widget.context if not IAddForm.providedBy(self.widget.form): dm = queryMultiAdapter((context, self.field), IDataManager) else: dm = None current_field_value = (dm.query() if ((dm is not None) and self.field.interface.providedBy(context)) else None) if not current_field_value or current_field_value == NO_VALUE: current_field_value = [] if not isinstance(current_field_value, list): current_field_value = [current_field_value] current_field_set = set(current_field_value) retvalue = [] if (INamedField.providedBy(self.field)): value_type = self.field._type else: value_type = self.field.value_type._type if not value: return value elif not isinstance(value, list): value = [value] for item in value: if item['new']: retvalue.append( value_type(data=item['file'].read(), filename=item['name'])) else: for existing_file in current_field_set: if existing_file.filename == item['name']: retvalue.append(existing_file) if (INamedField.providedBy(self.field)): return retvalue[0] else: return retvalue
def _add_form_portal_type_default_view(self): """Return the default view of the portal type of this add form if we are on a add form """ if not IAddForm.providedBy(getattr(self.form, '__parent__', None)): return '' portal_type = getattr(getattr(self.form, '__parent__', self.form), 'portal_type', None) if portal_type is None: return '' types_tool = api.portal.get_tool('portal_types') fti = getattr(types_tool, portal_type, None) if fti is None: return '' behaviors = getattr(fti, 'behaviors', None) or [] if 'plone.app.blocks.layoutbehavior.ILayoutAware' not in behaviors: return '' return fti.default_view
def update(self): form = self.__parent__ if IFormWrapper.providedBy(form): form = form.form_instance if not IAddForm.providedBy(form): return uuid = self.request.form.get('translation') language = self.request.form.get('language') if not uuid or not language: return obj = getObjectByuuid(self.context, uuid) context_state = getMultiAdapter((obj, self.request), name=u"plone_context_state") # This is now the parent of the item that we're trying to # create a new translation for! obj = context_state.parent() # If it's the site root, then we're done. if IPloneSiteRoot.providedBy(obj): return # Now we just need to check if the parent has already been # translated into the required language in which case we're # also done. translations = ITranslationGraph(obj).getTranslations() if language in dict(translations): return # Okay, we'll show the notice. self.available = True self.folder = obj self.language = self.request.locale.displayNames.languages.\ get(language)
def _add_form_portal_type_default_view(self): """Return the default view of the portal type of this add form if we are on a add form """ if not IAddForm.providedBy(getattr(self.form, '__parent__', None)): return '' portal_type = getattr(getattr( self.form, '__parent__', self.form), 'portal_type', None) if portal_type is None: return '' types_tool = api.portal.get_tool('portal_types') fti = getattr(types_tool, portal_type, None) if fti is None: return '' behaviors = getattr(fti, 'behaviors', None) or [] if 'plone.app.blocks.layoutbehavior.ILayoutAware' not in behaviors: return '' return fti.default_view
def _base_args(self): """Method which will calculate _base class arguments. Returns (as python dictionary): - `pattern`: pattern name - `pattern_options`: pattern options - `name`: field name - `value`: field value :returns: Arguments which will be passed to _base :rtype: dict """ args = super(AjaxSelectWidget, self)._base_args() args['name'] = self.name args['value'] = self.value args.setdefault('pattern_options', {}) field_name = self.field and self.field.__name__ or None context = self.context # We need special handling for AddForms if IAddForm.providedBy(getattr(self, 'form')): context = self.form args['pattern_options'] = dict_merge( get_ajaxselect_options(context, args['value'], self.separator, self.vocabulary, self.vocabulary_view, field_name), args['pattern_options']) # ISequence represents an orderable collection if ISequence.providedBy(self.field) or self.orderable: args['pattern_options']['orderable'] = True return args
def _add_form_portal_type_default_view(self): """Return the default view of the portal type of this add form if we are on a add form """ if not IAddForm.providedBy(getattr(self.form, '__parent__', None)): return '' portal_type = getattr(getattr(self.form, '__parent__', self.form), 'portal_type', None) if portal_type is None: return '' types_tool = api.portal.get_tool('portal_types') fti = getattr(types_tool, portal_type, None) if fti is None: return '' behaviors = getattr(fti, 'behaviors', None) or [] if not (LAYOUT_BEHAVIORS & set(behaviors)): return '' return fti.default_view
def _add_form_portal_type_default_view(self): """Return the default view of the portal type of this add form if we are on a add form """ if not IAddForm.providedBy(getattr(self.form, '__parent__', None)): return '' portal_type = getattr(getattr( self.form, '__parent__', self.form), 'portal_type', None) if portal_type is None: return '' types_tool = api.portal.get_tool('portal_types') fti = getattr(types_tool, portal_type, None) if fti is None: return '' behaviors = getattr(fti, 'behaviors', None) or [] if not (LAYOUT_BEHAVIORS & set(behaviors)): return '' return fti.default_view
def render(self): """Render widget. :returns: Widget's HTML. :rtype: string """ if self.mode != 'display': return super(FileUploadWidget, self).render() if not IAddForm.providedBy(self.form): dm = queryMultiAdapter((self.context, self.field,), IDataManager) else: dm = None ret_value = '<div class="files">' current_field_value = ( dm.query() if ((dm is not None) and self.field.interface.providedBy(self.context)) else None ) if current_field_value and current_field_value != NO_VALUE: if not isinstance(current_field_value, list): current_field_value = [current_field_value] current_field_set = set(current_field_value) for item in current_field_set: ret_value = ret_value + '<div class="existfileupload">' dl_url = '%s/++widget++%s/@@downloadexisting/' % ( self.request.getURL(), self.name) + item.filename ret_value = ret_value + '<a href=' + dl_url + '>' ret_value = ret_value + '<span class="filename">' + item.filename + '</span>' size = self.formatSize(item.getSize()) ret_value = ret_value + '<span class="filesize"> ' + size + '</span>' ret_value = ret_value + '</div>' ret_value = ret_value + '</div>' return ret_value
def toFieldValue(self, value): """Converts the value to a storable form.""" context = self.widget.context tmpdir = gettempdir() if not IAddForm.providedBy(self.widget.form): dm = queryMultiAdapter((context, self.field), IDataManager) else: dm = None current_field_value = ( dm.query() if ((dm is not None) and self.field.interface.providedBy(context)) else None ) if not current_field_value or current_field_value == NO_VALUE: current_field_value = [] if not isinstance(current_field_value, list): current_field_value = [current_field_value] current_field_set = set(current_field_value) retvalue = [] value_type = self.field.value_type._type if not value: return value elif not isinstance(value, list): value = [value] for item in value: if item['new']: retvalue.append(value_type(data=item['file'].read(), filename=item['name'])) filepath = join(tmpdir, item['temp']) os.remove(filepath) else: for existing_file in current_field_set: if existing_file.filename == item['name']: retvalue.append(existing_file) return retvalue
def update(self): isForm = IEditForm.providedBy(self.form) or IAddForm.providedBy( self.form) if not isForm: return if not hasattr(self.form, 'portal_type'): return if self.form.portal_type == 'organization': self.remove('logo') self.remove('activity') self.remove('IContactDetails.im_handle') self.remove('IContactDetails.country') self.remove('IContactDetails.cell_phone') self.remove('IContactDetails.fax') self.remove('IContactDetails.region') sm = getSecurityManager() if not sm.checkPermission('RIC: Administer website', self.context): self.form.fields['IBasic.title'].mode = 'display' self.form.fields['organization_type'].mode = 'display' contactFields = self.form.groups[0].fields #contactFields['IContactDetails.email'].field.required = True elif self.form.portal_type == 'person': self.remove('gender') self.remove('person_title') self.remove('photo') self.remove('IContactDetails.im_handle') self.remove('IContactDetails.fax') self.remove('IContactDetails.country') self.remove('IContactDetails.region') self.remove('IContactDetails.website') self.form.fields['firstname'].field.required = True contactFields = self.form.groups[0].fields contactFields['IContactDetails.email'].field.required = True
def update(self): isForm = IEditForm.providedBy(self.form) or IAddForm.providedBy(self.form) if not isForm: return if not hasattr(self.form, 'portal_type'): return if self.form.portal_type == 'organization': self.remove('logo') self.remove('activity') self.remove('IContactDetails.im_handle') self.remove('IContactDetails.country') contactFields = self.form.groups[0].fields contactFields['IContactDetails.email'].field.required = True elif self.form.portal_type == 'person': self.remove('gender') self.remove('person_title') self.remove('photo') self.remove('IContactDetails.im_handle') self.remove('IContactDetails.country') contactFields = self.form.groups[0].fields contactFields['IContactDetails.email'].field.required = True
def _base_args(self): """Method which will calculate _base class arguments. Returns (as python dictionary): - `pattern`: pattern name - `pattern_options`: pattern options :returns: Arguments which will be passed to _base :rtype: dict """ args = super(FileUploadWidget, self)._base_args() url = '%s/++widget++%s/@@upload/' % ( self.request.getURL(), self.name) args.setdefault('pattern_options', {}) args['pattern_options'] = {'url': url} args['pattern_options']['paramName'] = self.name if (INamedField.providedBy(self.field)): self.maxFiles = 1 args['pattern_options']['maxFiles'] = self.maxFiles args['pattern_options']['isWidget'] = True args['pattern_options']['showTitle'] = False args['pattern_options']['autoCleanResults'] = False self.cleanup() loaded = [] extractName = self.name + "uploaded" if getattr(self.request, extractName, None) is not None: files = self.request[extractName] if files: extracted = json.loads(str(files)) for extracted_file in extracted: if extracted_file['name'] != extracted_file['tmpname']: tmpdir = gettempdir() path = join(tmpdir, extracted_file['tmpname']) file_ = open(path, 'r+b') file_.seek(0, 2) # end of file tmpsize = file_.tell() file_.seek(0) file_.close() dl_url = '%s/++widget++%s/@@download/' % ( self.request.getURL(), self.name) + (extracted_file['tmpname'] + '?name=' + extracted_file['name']) newfile = {'tmpname': extracted_file['tmpname'], 'size': tmpsize, 'url': dl_url, 'name': extracted_file['name']} loaded.append(newfile) if not IAddForm.providedBy(self.form): dm = queryMultiAdapter((self.context, self.field,), IDataManager) else: dm = None current_field_value = ( dm.query() if ((dm is not None) and self.field.interface.providedBy(self.context)) else None ) if current_field_value and current_field_value != NO_VALUE: if not isinstance(current_field_value, list): current_field_value = [current_field_value] current_field_set = set(current_field_value) for item in current_field_set: dl_url = '%s/++widget++%s/@@downloadexisting/' % ( self.request.getURL(), self.name) + item.filename info = {'name': item.filename, 'tmpname': item.filename, 'size': item.getSize(), 'url': dl_url, } loaded.append(info) args['pattern_options']['existing'] = loaded return args
def autosave(event): # noqa context = getattr(event, 'object', None) request = getattr(context, 'REQUEST', getRequest()) if not request.URL.endswith('/@@z3cform_validate_field'): return view = getattr(request, 'PUBLISHED', None) form = getattr(view, 'context', None) if getattr(aq_base(form), 'form_instance', None): form = form.form_instance if IAddForm.providedBy(form): fti = queryUtility(IDexterityFTI, name=form.portal_type) if not isDraftable(fti): return draft = getCurrentDraft(request, create=True) target = getattr(draft, '_draftAddFormTarget', None) if target is None: target = createContent(form.portal_type) target.id = '' IMutableUUID(target).set('++add++{0}'.format(form.portal_type)) draft._draftAddFormTarget = target target = target.__of__(context) else: fti = queryUtility(IDexterityFTI, name=context.portal_type) if not isDraftable(fti): return draft = getCurrentDraft(request, create=True) target = context fti = queryUtility(IDexterityFTI, name=target.portal_type) if not isDraftable(fti): return if not getattr(form, 'extractData', None): return data, errors = form.extractData() if not errors: content = DraftProxy(draft, target) # Drop known non-draftable values data = dict([(k, v) for k, v in data.items() if k not in AUTOSAVE_BLACKLIST]) # noqa # Values are applied within savepoint to allow revert of any # unexpected side-effects from setting field values sp = transaction.savepoint(optimistic=True) try: applyChanges(form, content, data) for group in getattr(form, 'groups', []): applyChanges(group, content, data) except Exception: # If shortname was not blacklisted, it could fail because the # behavior trying to rename object on add form. pass values = dict(draft.__dict__) sp.rollback() for key, value in values.items(): setattr(draft, key, value) # Disable Plone 5 implicit CSRF to update draft if HAS_PLONE_PROTECT: alsoProvides(request, IDisableCSRFProtection)