diff --git a/news/130.feature b/news/130.feature new file mode 100644 index 0000000..9e8ad04 --- /dev/null +++ b/news/130.feature @@ -0,0 +1 @@ +Allows working copy of Plone Site. @wesleybl diff --git a/plone/app/iterate/base.py b/plone/app/iterate/base.py index 062574c..d38da35 100644 --- a/plone/app/iterate/base.py +++ b/plone/app/iterate/base.py @@ -65,7 +65,12 @@ def checkout(self, container): # use the object copier to checkout the content to the container copier = queryAdapter(self.context, IObjectCopier) - working_copy, relation = copier.copyTo(container) + # The container for the Portal's working copy is the Portal itself. + if self.context.portal_type == "Plone Site": + working_copy_container = self.context + else: + working_copy_container = container + working_copy, relation = copier.copyTo(working_copy_container) # publish the event for any subscribers notify(CheckoutEvent(self.context, working_copy, relation)) diff --git a/plone/app/iterate/containers.py b/plone/app/iterate/containers.py index c22142c..da1cc18 100644 --- a/plone/app/iterate/containers.py +++ b/plone/app/iterate/containers.py @@ -64,11 +64,11 @@ def __init__(self, context): @property def available(self): - return bool( - getSecurityManager().checkPermission( - AddPortalContent, aq_parent(aq_inner(self.context)) - ) - ) + obj = aq_inner(self.context) + # In Plone Site checkout, the working copy container is the portal itself. + if obj.portal_type != "Plone Site": + obj = aq_parent(obj) + return bool(getSecurityManager().checkPermission(AddPortalContent, obj)) def __call__(self): if not self.available: diff --git a/plone/app/iterate/dexterity/configure.zcml b/plone/app/iterate/dexterity/configure.zcml index 0457c7b..2909fdf 100644 --- a/plone/app/iterate/dexterity/configure.zcml +++ b/plone/app/iterate/dexterity/configure.zcml @@ -29,4 +29,8 @@ + + + + diff --git a/plone/app/iterate/dexterity/copier.py b/plone/app/iterate/dexterity/copier.py index bfa8ab4..3e4d47f 100644 --- a/plone/app/iterate/dexterity/copier.py +++ b/plone/app/iterate/dexterity/copier.py @@ -98,6 +98,10 @@ def _replaceBaseline(self, baseline): return baseline def _reassembleWorkingCopy(self, new_baseline, baseline): + # Does not change Plone Site permissions. + if new_baseline.portal_type == "Plone Site": + return new_baseline + # reattach the source's workflow history, try avoid a dangling ref try: new_baseline.workflow_history = PersistentMapping( @@ -171,11 +175,20 @@ def checkin(self, checkin_message): class FolderishContentCopier(ContentCopier): def _copyBaseline(self, container): + if self.context.portal_type == "Plone Site": + portal_type = "Document" + else: + portal_type = self.context.portal_type obj = createContentInContainer( container, - self.context.portal_type, + portal_type, id=f"working_copy_of_{self.context.id}", ) + # Since the working copy of the Portal is originally a Document, + # we force its portal_type to "Plone Site", so that the "Plone Site" + # schema is used. + if self.context.portal_type == "Plone Site": + obj.portal_type = "Plone Site" # copy all field values from the baseline to the working copy for schema in iterSchemata(self.context): diff --git a/plone/app/iterate/tests/test_containers.py b/plone/app/iterate/tests/test_containers.py index b79735d..d18df35 100644 --- a/plone/app/iterate/tests/test_containers.py +++ b/plone/app/iterate/tests/test_containers.py @@ -219,11 +219,11 @@ def test_container_control_checkin_allowed_with_no_policy(self): self.assertFalse(control.checkin_allowed()) def test_container_control_checkout_allowed_with_no_policy(self): - control = Control(self.portal, self.layer["request"]) + control = Control(self.portal.docs, self.layer["request"]) self.assertFalse(control.checkout_allowed()) def test_container_control_cancel_allowed_with_no_policy(self): - control = Control(self.portal, self.layer["request"]) + control = Control(self.portal.docs, self.layer["request"]) self.assertFalse(control.cancel_allowed()) def test_container_control_cancel_on_original_does_not_delete_original(self): diff --git a/plone/app/iterate/tests/test_iterate.py b/plone/app/iterate/tests/test_iterate.py index 93b9397..dc72b04 100644 --- a/plone/app/iterate/tests/test_iterate.py +++ b/plone/app/iterate/tests/test_iterate.py @@ -126,11 +126,11 @@ def test_control_checkin_allowed_with_no_policy(self): self.assertFalse(control.checkin_allowed()) def test_control_checkout_allowed_with_no_policy(self): - control = Control(self.portal, self.layer["request"]) + control = Control(self.portal.docs, self.layer["request"]) self.assertFalse(control.checkout_allowed()) def test_control_cancel_allowed_with_no_policy(self): - control = Control(self.portal, self.layer["request"]) + control = Control(self.portal.docs, self.layer["request"]) self.assertFalse(control.cancel_allowed()) def test_control_cancel_on_original_does_not_delete_original(self):