Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with slots #6

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
54 changes: 54 additions & 0 deletions src/collective/volto/formsupport/datamanager/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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", [])
6 changes: 6 additions & 0 deletions src/collective/volto/formsupport/datamanager/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
<implements interface="souper.plone.interfaces.ISoupRoot" />
</class>

<class class="Products.CMFPlone.interfaces.siteroot.IPloneSiteRoot">
<implements interface="souper.plone.interfaces.ISoupRoot" />
</class>

<!-- register the catalog -->
<utility
provides="souper.interfaces.ICatalogFactory"
Expand All @@ -16,4 +20,6 @@
/>

<adapter factory=".catalog.FormDataStore" />
<adapter factory=".catalog.PloneSiteFormDataStore" />
<adapter factory=".catalog.SlotDataStore" />
</configure>
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@
permission="cmf.ModifyPortalContent"
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

<plone:service
method="GET"
name="@form-data"
for="*"
factory=".form_data.FormDataGet"
permission="cmf.ModifyPortalContent"
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

<plone:service
method="GET"
name="@form-data"
for="Products.CMFPlone.interfaces.siteroot.IPloneSiteRoot"
factory=".form_data.FormDataGet"
permission="cmf.ModifyPortalContent"
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

<adapter factory=".form_data.FormData" name="form-data"/>

<plone:service
Expand All @@ -22,6 +41,15 @@
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

<plone:service
method="GET"
name="@form-data-clear"
for="Products.CMFPlone.interfaces.siteroot.IPloneSiteRoot"
factory=".clear.FormDataClear"
permission="cmf.ModifyPortalContent"
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

<plone:service
method="GET"
name="@form-data-export"
Expand All @@ -31,4 +59,13 @@
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

<plone:service
method="GET"
name="@form-data-export"
for="Products.CMFPlone.interfaces.siteroot.IPloneSiteRoot"
factory=".csv.FormDataExportGet"
permission="cmf.ModifyPortalContent"
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

</configure>
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,21 @@
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

<plone:service
method="POST"
name="@submit-form"
for="*"
factory=".post.FallbackSubmitPost"
permission="zope2.View"
/>

<plone:service
method="POST"
name="@submit-form"
for="plone.dexterity.interfaces.IDexterityContent"
factory=".post.FallbackSubmitPost"
permission="zope2.View"
layer="collective.volto.formsupport.interfaces.ICollectiveVoltoFormsupportLayer"
/>

</configure>
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {}
15 changes: 9 additions & 6 deletions src/collective/volto/formsupport/upgrades.py
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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("/")
Expand Down
25 changes: 19 additions & 6 deletions src/collective/volto/formsupport/utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from collections import deque
from plone.restapi.slots.interfaces import ISlot
from plone.restapi.slots.interfaces import ISlots

import copy
import json
import six


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
"""

Expand All @@ -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
Loading