Skip to content

Commit

Permalink
Override default DX add form to obtain renamed IDs correctly (#2370)
Browse files Browse the repository at this point in the history
* Patch DX default add form to handle renamed IDs

* Fix catalog of sample containers view

* Changelog updated
  • Loading branch information
ramonski authored Sep 1, 2023
1 parent e2a879b commit bed7e68
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
2.5.0 (unreleased)
------------------

- #2370 Override default DX add form to obtain renamed IDs correctly
- #2368 Drop usage of portal_catalog tool
- #2369 Allow to set a custom comment for when a result is out of range
- #2367 Contact catalog
Expand Down
3 changes: 3 additions & 0 deletions src/senaite/core/browser/controlpanel/samplecontainers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from bika.lims import senaiteMessageFactory as _
from bika.lims.utils import get_link_for
from senaite.app.listing import ListingView
from senaite.core.catalog import SETUP_CATALOG


class SampleContainersView(ListingView):
Expand All @@ -33,6 +34,8 @@ class SampleContainersView(ListingView):
def __init__(self, context, request):
super(SampleContainersView, self).__init__(context, request)

self.catalog = SETUP_CATALOG

self.contentFilter = {
"portal_type": "SampleContainer",
"sort_on": "sortable_title",
Expand Down
78 changes: 78 additions & 0 deletions src/senaite/core/browser/dexterity/add.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-

from AccessControl import Unauthorized
from Acquisition import aq_base
from Acquisition import aq_inner
from plone.app.uuid.utils import uuidToObject
from plone.dexterity.browser.add import DefaultAddForm as BaseAddForm
from plone.dexterity.browser.add import DefaultAddView as BaseAddView
from plone.dexterity.interfaces import IDexterityFTI
from plone.uuid.interfaces import IUUID
from zope.component import getUtility
from zope.container.interfaces import INameChooser


class DefaultAddForm(BaseAddForm):
"""Patched Add Form to handle renameAfterCreation of DX objects
"""

def add(self, object):
"""Patched add method to use our own addContentToContainer
"""
fti = getUtility(IDexterityFTI, name=self.portal_type)
new_object = addContentToContainer(self.container, object)

if fti.immediate_view:
self.immediate_view = "/".join(
[self.container.absolute_url(), new_object.id, fti.immediate_view]
)
else:
self.immediate_view = "/".join(
[self.container.absolute_url(), new_object.id]
)


class DefaultAddView(BaseAddView):
form = DefaultAddForm


def addContentToContainer(container, object, checkConstraints=True):
"""Add an object to a container (patched)
original code located in `plone.dexterity.utils module`
The patched version of this function uses the object ID to get the object
from the container instead of the return value of
`container._setObject(name, object)`
This ensures we have the generated ID the object was renamed to *after* the
object was added to the container!
"""
if not hasattr(aq_base(object), "portal_type"):
raise ValueError("object must have its portal_type set")

container = aq_inner(container)
if checkConstraints:
container_fti = container.getTypeInfo()

fti = getUtility(IDexterityFTI, name=object.portal_type)
if not fti.isConstructionAllowed(container):
raise Unauthorized("Cannot create %s" % object.portal_type)

if container_fti is not None and not container_fti.allowType(
object.portal_type
):
raise ValueError("Disallowed subobject type: %s" % object.portal_type)

name = getattr(aq_base(object), "id", None)
name = INameChooser(container).chooseName(name, object)
object.id = name

container._setObject(name, object)
try:
# PATCH HERE: Use object.id to ensure we have the renamed object ID
return container._getOb(object.id)
except AttributeError:
uuid = IUUID(object)
return uuidToObject(uuid)
15 changes: 15 additions & 0 deletions src/senaite/core/browser/dexterity/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@
xmlns:zcml="http://namespaces.zope.org/zcml"
i18n_domain="plone">

<!-- Standard add view and form - invoked from ++add++ traverser -->
<adapter
for="Products.CMFCore.interfaces.IFolderish
senaite.core.interfaces.ISenaiteFormLayer
plone.dexterity.interfaces.IDexterityFTI"
provides="zope.publisher.interfaces.browser.IBrowserPage"
factory=".add.DefaultAddView"
/>
<class class=".add.DefaultAddView">
<require
permission="cmf.AddPortalContent"
interface="zope.publisher.interfaces.browser.IBrowserPage"
/>
</class>

<!-- Override form/field/widget macros for edit mode -->
<browser:page
name="ploneform-macros"
Expand Down

0 comments on commit bed7e68

Please sign in to comment.