Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/1875.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed block deserializers not running for control panel fields @JeffersonBledsoe
8 changes: 6 additions & 2 deletions src/plone/restapi/deserializer/controlpanels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
from zope.schema import getFields
from zope.schema.interfaces import ValidationError

from plone.restapi.behaviors import IBlocks
from Acquisition import ImplicitAcquisitionWrapper

@implementer(IDexterityContent)

@implementer(IDexterityContent, IBlocks)
class FakeDXContext:
"""Fake DX content class, so we can reuse the DX field deserializers"""

Expand Down Expand Up @@ -47,6 +50,7 @@ def __call__(self, mask_validation_errors=True):

# Make a fake context
fake_context = FakeDXContext()
wrapped_context = ImplicitAcquisitionWrapper(fake_context, self.context)

for name, field in getFields(self.schema).items():
field_data = schema_data.setdefault(self.schema, {})
Expand All @@ -56,7 +60,7 @@ def __call__(self, mask_validation_errors=True):

if name in data:
deserializer = queryMultiAdapter(
(field, fake_context, self.request), IFieldDeserializer
(field, wrapped_context, self.request), IFieldDeserializer
)

try:
Expand Down
23 changes: 19 additions & 4 deletions src/plone/restapi/serializer/controlpanels/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from Acquisition import ImplicitAcquisitionWrapper
from plone.dexterity.interfaces import IDexterityContent
from plone.registry.interfaces import IRegistry
from plone.restapi.behaviors import IBlocks
from plone.restapi.controlpanels import IControlpanel
from plone.restapi.interfaces import IFieldSerializer
from plone.restapi.interfaces import ISerializeToJson
Expand All @@ -18,6 +20,11 @@

SERVICE_ID = "@controlpanels"

# Same class is in deserializer. Should centralise it.
@implementer(IDexterityContent, IBlocks)
class FakeDXContext:
"""Fake DX content class, so we can re-use the DX field deserializers"""


@implementer(ISerializeToJsonSummary)
@adapter(IControlpanel)
Expand Down Expand Up @@ -96,14 +103,22 @@ def __call__(self):

proxy = self.registry.forInterface(self.schema, prefix=self.schema_prefix)

# Temporarily provide IDexterityContent, so we can use DX field
# serializers
alsoProvides(proxy, IDexterityContent)
# Make a fake context and copy registry values onto it
fake_context = FakeDXContext()


# Copy all field values from the proxy to the fake context
# so that field serializers can properly adapt the context
for name in zope.schema.getFields(self.schema).keys():
setattr(fake_context, name, getattr(proxy, name, None))
alsoProvides(fake_context, self.schema)

wrapped_context = ImplicitAcquisitionWrapper(fake_context, self.controlpanel.context)

json_data = {}
for name, field in zope.schema.getFields(self.schema).items():
serializer = queryMultiAdapter(
(field, proxy, self.controlpanel.request), IFieldSerializer
(field, wrapped_context, self.controlpanel.request), IFieldSerializer
)
if serializer:
value = serializer()
Expand Down
Loading