diff --git a/src/collective/volto/formsupport/adapters/post.py b/src/collective/volto/formsupport/adapters/post.py index c7717541..7681f38d 100644 --- a/src/collective/volto/formsupport/adapters/post.py +++ b/src/collective/volto/formsupport/adapters/post.py @@ -18,6 +18,11 @@ import os +GLOBAL_FORM_REGISTRY_RECORD_ID = ( + "collective.volto.formsupport.interfaces.IGlobalFormStore.global_forms_config" +) + + @implementer(IPostAdapter) @adapter(Interface, Interface) class PostAdapter: @@ -29,8 +34,12 @@ def __init__(self, context, request): self.request = request self.form_data = self.extract_data_from_request() self.block_id = self.form_data.get("block_id", "") + self.global_form_id = self.extract_data_from_request().get("global_form_id", "") if self.block_id: - self.block = self.get_block_data(block_id=self.block_id) + self.block = self.get_block_data( + block_id=self.block_id, + global_form_id=self.form_data.get("global_form_id"), + ) def __call__(self): """ @@ -50,7 +59,10 @@ def extract_data_from_request(self): fixed_fields = [] transforms = api.portal.get_tool(name="portal_transforms") - block = self.get_block_data(block_id=form_data.get("block_id", "")) + block = self.get_block_data( + block_id=form_data.get("block_id", ""), + global_form_id=form_data.get("global_form_id"), + ) block_fields = [x.get("field_id", "") for x in block.get("subblocks", [])] for form_field in form_data.get("data", []): @@ -68,12 +80,24 @@ def extract_data_from_request(self): return form_data - def get_block_data(self, block_id): + def get_block_data(self, block_id, global_form_id): blocks = get_blocks(self.context) + global_form_id = global_form_id + if global_form_id: + global_forms = api.portal.get_registry_record( + GLOBAL_FORM_REGISTRY_RECORD_ID + ) + if global_forms: + blocks = {**blocks, **global_forms} if not blocks: return {} for id, block in blocks.items(): - if id != block_id: + # Prefer local forms it they're available, fall back to global form + if ( + id != block_id + and id != global_form_id + and block.get("global_form_id") != global_form_id + ): continue block_type = block.get("@type", "") if block_type != "form": diff --git a/src/collective/volto/formsupport/interfaces.py b/src/collective/volto/formsupport/interfaces.py index 16197df5..2f99771b 100644 --- a/src/collective/volto/formsupport/interfaces.py +++ b/src/collective/volto/formsupport/interfaces.py @@ -1,3 +1,5 @@ +from plone.restapi.controlpanels.interfaces import IControlpanel +from plone.schema import JSONField from zope.interface import Attribute from zope.interface import Interface from zope.interface.interfaces import IObjectEvent @@ -69,3 +71,9 @@ def data(): class IDataAdapter(Interface): def __call__(result, block_id=None): pass + + +class IGlobalFormStore(IControlpanel): + global_forms_config = JSONField( + title="Global forms", description="", required=True, default={} + ) diff --git a/src/collective/volto/formsupport/profiles/default/metadata.xml b/src/collective/volto/formsupport/profiles/default/metadata.xml index 4a9d2560..d640ec01 100644 --- a/src/collective/volto/formsupport/profiles/default/metadata.xml +++ b/src/collective/volto/formsupport/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 1301 + 1302 profile-collective.volto.otp:default diff --git a/src/collective/volto/formsupport/profiles/default/registry/main.xml b/src/collective/volto/formsupport/profiles/default/registry/main.xml index b6314fd3..938fc285 100644 --- a/src/collective/volto/formsupport/profiles/default/registry/main.xml +++ b/src/collective/volto/formsupport/profiles/default/registry/main.xml @@ -4,5 +4,6 @@ > + diff --git a/src/collective/volto/formsupport/restapi/deserializer/blocks.py b/src/collective/volto/formsupport/restapi/deserializer/blocks.py index 943ec940..95e76e5a 100644 --- a/src/collective/volto/formsupport/restapi/deserializer/blocks.py +++ b/src/collective/volto/formsupport/restapi/deserializer/blocks.py @@ -1,12 +1,34 @@ +from plone.api.portal import get_registry_record +from plone.api.portal import set_registry_record from plone.dexterity.interfaces import IDexterityContent from plone.restapi.bbb import IPloneSiteRoot from plone.restapi.interfaces import IBlockFieldDeserializationTransformer from Products.PortalTransforms.transforms.safe_html import SafeHTML +from uuid import uuid4 from zope.component import adapter from zope.interface import implementer from zope.publisher.interfaces.browser import IBrowserRequest +GLOBAL_FORM_REGISTRY_RECORD_ID = ( + "collective.volto.formsupport.interfaces.IGlobalFormStore.global_forms_config" +) + + +def update_global_forms(value): + global_form_id = value.get("global_form_id") + + if not global_form_id: + global_form_id = str(uuid4()) + + global_forms_record = get_registry_record(GLOBAL_FORM_REGISTRY_RECORD_ID) + global_forms_record[global_form_id] = value + set_registry_record(GLOBAL_FORM_REGISTRY_RECORD_ID, global_forms_record) + + value["global_form_id"] = global_form_id + return value + + class FormBlockDeserializerBase: """FormBlockDeserializerBase.""" @@ -25,6 +47,7 @@ def __call__(self, value): if value.get("send_message", ""): transform = SafeHTML() value["send_message"] = transform.scrub_html(value["send_message"]) + value = update_global_forms(value) return value 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 5cef8c43..a8d45079 100644 --- a/src/collective/volto/formsupport/restapi/services/submit_form/post.py +++ b/src/collective/volto/formsupport/restapi/services/submit_form/post.py @@ -56,11 +56,10 @@ def __init__(self, context, request): self.form_data_adapter = getMultiAdapter( (self.context, self.request), IPostAdapter ) - self.form_data = self.get_form_data() - self.block_id = self.form_data.get("block_id", "") - - if self.block_id: - self.block = self.get_block_data(block_id=self.block_id) + # We've already done all the work to get this data, let's reuse it. + self.form_data = self.form_data_adapter.form_data + self.block_id = self.form_data_adapter.block_id + self.block = self.form_data_adapter.block def reply(self): store_action = self.block.get("store", False) diff --git a/src/collective/volto/formsupport/upgrades.zcml b/src/collective/volto/formsupport/upgrades.zcml index b5991637..4212ab77 100644 --- a/src/collective/volto/formsupport/upgrades.zcml +++ b/src/collective/volto/formsupport/upgrades.zcml @@ -40,4 +40,12 @@ handler=".upgrades.to_1301" /> + +