diff --git a/src/collective/volto/formsupport/datamanager/catalog.py b/src/collective/volto/formsupport/datamanager/catalog.py index c92317ae..05a1cb05 100644 --- a/src/collective/volto/formsupport/datamanager/catalog.py +++ b/src/collective/volto/formsupport/datamanager/catalog.py @@ -6,7 +6,10 @@ from copy import deepcopy from datetime import datetime from plone.dexterity.interfaces import IDexterityContent +from plone.i18n.normalizer.interfaces import IIDNormalizer from plone.restapi.deserializer import json_body +from plone.restapi.slots.interfaces import ISlot +from Products.CMFPlone.interfaces.siteroot import IPloneSiteRoot from repoze.catalog.catalog import Catalog from repoze.catalog.indexes.field import CatalogFieldIndex from souper.interfaces import ICatalogFactory @@ -51,6 +54,7 @@ def get_form_fields(self): if not blocks: return {} + form_block = {} for id, block in blocks.items(): if id != self.block_id: @@ -118,3 +122,53 @@ def delete(self, id): def clear(self): self.soup.clear() + + +@implementer(IFormDataStore) +@adapter(IPloneSiteRoot, Interface) +class PloneSiteFormDataStore(FormDataStore): + def get_form_fields(self): + # TODO: should this be getProperty? + blocks = get_blocks(self.context) + + if not blocks: + return {} + + form_block = {} + + for id, block in blocks.items(): + if id != self.block_id: + continue + block_type = block.get("@type", "") + if block_type == "form": + form_block = deepcopy(block) + + if not form_block: + return {} + + return form_block.get("subblocks", []) + + +@implementer(IFormDataStore) +@adapter(ISlot, Interface) +class SlotDataStore(FormDataStore): + def get_form_fields(self): + # TODO: should this be getProperty? + blocks = get_blocks(self.context) + + if not blocks: + return {} + + form_block = {} + + for id, block in blocks.items(): + if id != self.block_id: + continue + block_type = block.get("@type", "") + if block_type == "form": + form_block = deepcopy(block) + + if not form_block: + return {} + + return form_block.get("subblocks", []) diff --git a/src/collective/volto/formsupport/datamanager/configure.zcml b/src/collective/volto/formsupport/datamanager/configure.zcml index b492ad26..bf50574f 100644 --- a/src/collective/volto/formsupport/datamanager/configure.zcml +++ b/src/collective/volto/formsupport/datamanager/configure.zcml @@ -8,6 +8,10 @@ + + + + + + diff --git a/src/collective/volto/formsupport/restapi/services/form_data/configure.zcml b/src/collective/volto/formsupport/restapi/services/form_data/configure.zcml index 1ec1ea1a..4f2b74bd 100644 --- a/src/collective/volto/formsupport/restapi/services/form_data/configure.zcml +++ b/src/collective/volto/formsupport/restapi/services/form_data/configure.zcml @@ -11,6 +11,25 @@ permission="cmf.ModifyPortalContent" layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer" /> + + + + + + + + + diff --git a/src/collective/volto/formsupport/restapi/services/submit_form/configure.zcml b/src/collective/volto/formsupport/restapi/services/submit_form/configure.zcml index 80fdc6be..e158d62a 100644 --- a/src/collective/volto/formsupport/restapi/services/submit_form/configure.zcml +++ b/src/collective/volto/formsupport/restapi/services/submit_form/configure.zcml @@ -12,4 +12,21 @@ layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer" /> + + + + diff --git a/src/collective/volto/formsupport/restapi/services/submit_form/post.py b/src/collective/volto/formsupport/restapi/services/submit_form/post.py index e784e41e..fc20ac82 100644 --- a/src/collective/volto/formsupport/restapi/services/submit_form/post.py +++ b/src/collective/volto/formsupport/restapi/services/submit_form/post.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - from collective.volto.formsupport import _ from collective.volto.formsupport.interfaces import ICaptchaSupport from collective.volto.formsupport.interfaces import IFormDataStore @@ -13,7 +12,9 @@ from plone.restapi.deserializer import json_body from plone.restapi.services import Service from Products.CMFPlone.interfaces.controlpanel import IMailSchema -from xml.etree.ElementTree import ElementTree, Element, SubElement +from xml.etree.ElementTree import Element +from xml.etree.ElementTree import ElementTree +from xml.etree.ElementTree import SubElement from zExceptions import BadRequest from zope.component import getMultiAdapter from zope.component import getUtility @@ -170,8 +171,10 @@ def validate_attachments(self): def get_block_data(self, block_id): blocks = get_blocks(self.context) + if not blocks: return {} + for id, block in blocks.items(): if id != block_id: continue @@ -384,3 +387,22 @@ def store_data(self): res = store.add(data=self.filter_parameters()) if not res: raise BadRequest("Unable to store data") + + +class FallbackSubmitPost(SubmitPost): + """Submit post service for plone root""" + + def get_block_data(self, block_id): + blocks = get_blocks(self.context) + + if not blocks: + return {} + + for id, block in blocks.items(): + if id != block_id: + continue + block_type = block.get("@type", "") + if block_type != "form": + continue + return block + return {} diff --git a/src/collective/volto/formsupport/upgrades.py b/src/collective/volto/formsupport/upgrades.py index 1ae3aff8..4f9ce801 100644 --- a/src/collective/volto/formsupport/upgrades.py +++ b/src/collective/volto/formsupport/upgrades.py @@ -1,15 +1,15 @@ # -*- coding: utf-8 -*- from Acquisition import aq_base +from collective.volto.formsupport.interfaces import IFormDataStore from copy import deepcopy from plone import api from plone.dexterity.utils import iterSchemata -from zope.schema import getFields -from collective.volto.formsupport.interfaces import IFormDataStore -from zope.component import getMultiAdapter -from zope.globalrequest import getRequest +from plone.i18n.normalizer.interfaces import IIDNormalizer from souper.soup import Record +from zope.component import getMultiAdapter from zope.component import getUtility -from plone.i18n.normalizer.interfaces import IIDNormalizer +from zope.globalrequest import getRequest +from zope.schema import getFields try: @@ -129,7 +129,10 @@ def fix_data(blocks, context): portal = api.portal.get() portal_blocks = getattr(portal, "blocks", "") if portal_blocks: - blocks = json.loads(portal_blocks) + if isinstance(portal_blocks, str): + blocks = json.loads(portal_blocks) + else: + blocks = portal_blocks res = fix_data(blocks, portal) if res: fixed_contents.append("/") diff --git a/src/collective/volto/formsupport/utils.py b/src/collective/volto/formsupport/utils.py index ed3f1d0a..aa143e35 100644 --- a/src/collective/volto/formsupport/utils.py +++ b/src/collective/volto/formsupport/utils.py @@ -1,4 +1,6 @@ from collections import deque +from plone.restapi.slots.interfaces import ISlot +from plone.restapi.slots.interfaces import ISlots import copy import json @@ -6,7 +8,8 @@ def flatten_block_hierachy(blocks): - """Given some blocks, return all contained blocks, including "subblocks" + """ Given some blocks, return all contained blocks, including "subblocks" + This allows embedding the form block into something like columns datastorage """ @@ -21,19 +24,29 @@ def flatten_block_hierachy(blocks): if "data" in block_value: if isinstance(block_value["data"], dict): if "blocks" in block_value["data"]: - queue.extend(list(block_value["data"]["blocks"].items())) + queue.extend(list( + block_value["data"]["blocks"].items())) if "blocks" in block_value: queue.extend(list(block_value["blocks"].items())) def get_blocks(context): - """Returns all blocks from a context, including those coming from slots""" - + """ Returns all blocks from a context, including those coming from slots + """ blocks = copy.deepcopy(getattr(context, "blocks", {})) if isinstance(blocks, six.text_type): blocks = json.loads(blocks) - flat = list(flatten_block_hierachy(blocks)) + if ISlot.providedBy(context): + return blocks + + slots = ISlots(context) + slot_names = slots.discover_slots() + + for name in slot_names: + flat = list((flatten_block_hierachy( + slots.get_data(name, full=True)['blocks'] or {}))) + blocks.update(flat) - return dict(flat) + return blocks