Passed
Push — 2.x ( e2a879...bed7e6 )
by Jordi
06:05
created

addContentToContainer()   B

Complexity

Conditions 7

Size

Total Lines 40
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 40
rs 7.9759
c 0
b 0
f 0
cc 7
nop 3
1
# -*- coding: utf-8 -*-
2
3
from AccessControl import Unauthorized
4
from Acquisition import aq_base
5
from Acquisition import aq_inner
6
from plone.app.uuid.utils import uuidToObject
7
from plone.dexterity.browser.add import DefaultAddForm as BaseAddForm
8
from plone.dexterity.browser.add import DefaultAddView as BaseAddView
9
from plone.dexterity.interfaces import IDexterityFTI
10
from plone.uuid.interfaces import IUUID
11
from zope.component import getUtility
12
from zope.container.interfaces import INameChooser
13
14
15
class DefaultAddForm(BaseAddForm):
16
    """Patched Add Form to handle renameAfterCreation of DX objects
17
    """
18
19
    def add(self, object):
20
        """Patched add method to use our own addContentToContainer
21
        """
22
        fti = getUtility(IDexterityFTI, name=self.portal_type)
23
        new_object = addContentToContainer(self.container, object)
24
25
        if fti.immediate_view:
26
            self.immediate_view = "/".join(
27
                [self.container.absolute_url(), new_object.id, fti.immediate_view]
28
            )
29
        else:
30
            self.immediate_view = "/".join(
31
                [self.container.absolute_url(), new_object.id]
32
            )
33
34
35
class DefaultAddView(BaseAddView):
36
    form = DefaultAddForm
37
38
39
def addContentToContainer(container, object, checkConstraints=True):
40
    """Add an object to a container (patched)
41
42
    original code located in `plone.dexterity.utils module`
43
44
    The patched version of this function uses the object ID to get the object
45
    from the container instead of the return value of
46
47
    `container._setObject(name, object)`
48
49
    This ensures we have the generated ID the object was renamed to *after* the
50
    object was added to the container!
51
    """
52
    if not hasattr(aq_base(object), "portal_type"):
53
        raise ValueError("object must have its portal_type set")
54
55
    container = aq_inner(container)
56
    if checkConstraints:
57
        container_fti = container.getTypeInfo()
58
59
        fti = getUtility(IDexterityFTI, name=object.portal_type)
60
        if not fti.isConstructionAllowed(container):
61
            raise Unauthorized("Cannot create %s" % object.portal_type)
62
63
        if container_fti is not None and not container_fti.allowType(
64
            object.portal_type
65
        ):
66
            raise ValueError("Disallowed subobject type: %s" % object.portal_type)
67
68
    name = getattr(aq_base(object), "id", None)
69
    name = INameChooser(container).chooseName(name, object)
70
    object.id = name
71
72
    container._setObject(name, object)
73
    try:
74
        # PATCH HERE: Use object.id to ensure we have the renamed object ID
75
        return container._getOb(object.id)
76
    except AttributeError:
77
        uuid = IUUID(object)
78
        return uuidToObject(uuid)
79