Skip to content

Commit

Permalink
backport dexterity copy flag patch.
Browse files Browse the repository at this point in the history
**Problem:**

When copying a DX container which has AT children, the UID of the AT
children was not updated.
The reason for the error is that the DX container copy did not have the
`_v_is_cp` flag while the AT children were processed and thus the flag
was not properly delegated.

**Solution:**

By copying the `_v_is_cp` and `_v_cp_refs flags` to the copy we have the
same behavior as it used to be with AT, which does fix the error.

- Issue: plone/Products.CMFPlone#1735
- Plone 4 fix: plone/plone.dexterity#60
- Plone 5 fix: plone/plone.dexterity#61
  • Loading branch information
jone committed Sep 1, 2016
1 parent c8b64af commit 3df04c1
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 3 deletions.
22 changes: 22 additions & 0 deletions README.rst
Expand Up @@ -6,6 +6,28 @@ Introduction

### INTRODUCTION ###


Backport of dexterity patch: set copy flags
-------------------------------------------

**Problem:**

When copying a DX container which has AT children, the UID of the AT
children was not updated.
The reason for the error is that the DX container copy did not have the
`_v_is_cp` flag while the AT children were processed and thus the flag
was not properly delegated.

**Solution:**

By copying the `_v_is_cp` and `_v_cp_refs flags` to the copy we have the
same behavior as it used to be with AT, which does fix the error.

- Issue: https://github.com/plone/Products.CMFPlone/issues/1735
- Plone 4 fix: https://github.com/plone/plone.dexterity/pull/60
- Plone 5 fix: https://github.com/plone/plone.dexterity/pull/61


Compatibility
-------------

Expand Down
11 changes: 10 additions & 1 deletion ftw/copymovepatches/configure.zcml
@@ -1,5 +1,14 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five">
xmlns:monkey="http://namespaces.plone.org/monkey"
i18n_domain="ftw.copymovepatches">

<monkey:patch
description="Backport dexterity copy flags"
class="plone.dexterity.content.PasteBehaviourMixin"
original="_getCopy"
replacement=".dx_copy_flags.PasteBehaviourMixin_getCopy"
ignoreOriginal="True"
/>

</configure>
19 changes: 19 additions & 0 deletions ftw/copymovepatches/dx_copy_flags.py
@@ -0,0 +1,19 @@
from plone.dexterity.content import PasteBehaviourMixin


# Patch for plone.dexterity.content.PasteBehaviourMixin._getCopy
def PasteBehaviourMixin_getCopy(self, container):
# Copy the _v_is_cp and _v_cp_refs flags from the original
# object (self) to the new copy.
# This has impact on how children will be handled.
# When the flags are missing, an Archetypes child object will not have
# the UID updated in some situations.
# Copied from Products.Archetypes.Referenceable.Referenceable._getCopy
is_cp_flag = getattr(self, '_v_is_cp', None)
cp_refs_flag = getattr(self, '_v_cp_refs', None)
ob = super(PasteBehaviourMixin, self)._getCopy(container)
if is_cp_flag:
setattr(ob, '_v_is_cp', is_cp_flag)
if cp_refs_flag:
setattr(ob, '_v_cp_refs', cp_refs_flag)
return ob
5 changes: 4 additions & 1 deletion ftw/copymovepatches/testing.py
@@ -1,10 +1,12 @@
from ftw.builder.testing import BUILDER_LAYER
from ftw.builder.testing import functional_session_factory
from ftw.builder.testing import set_builder_session_factory
from plone.app.testing import applyProfile
from plone.app.testing import FunctionalTesting
from plone.app.testing import PLONE_FIXTURE
from plone.app.testing import PloneSandboxLayer
from zope.configuration import xmlconfig
import ftw.copymovepatches.tests.builders


class FtwLayer(PloneSandboxLayer):
Expand All @@ -16,11 +18,12 @@ def setUpZope(self, app, configurationContext):
' <include package="z3c.autoinclude" file="meta.zcml" />'
' <includePlugins package="plone" />'
' <includePluginsOverrides package="plone" />'
' <include package="ftw.copymovepatches.tests" file="profiles.zcml" />'
'</configure>',
context=configurationContext)

def setUpPloneSite(self, portal):
pass
applyProfile(portal, 'ftw.copymovepatches.tests:default')


FTW_FIXTURE = FtwLayer()
Expand Down
9 changes: 9 additions & 0 deletions ftw/copymovepatches/tests/builders.py
@@ -0,0 +1,9 @@
from ftw.builder import builder_registry
from ftw.builder.dexterity import DexterityBuilder


class DXContainerBuilder(DexterityBuilder):
portal_type = 'DXContainer'


builder_registry.register('dx container', DXContainerBuilder)
14 changes: 14 additions & 0 deletions ftw/copymovepatches/tests/profiles.zcml
@@ -0,0 +1,14 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
xmlns:i18n="http://namespaces.zope.org/i18n"
i18n_domain="bl.web">

<genericsetup:registerProfile
title="bl.web.tests"
name="default"
directory="profiles/default"
provides="Products.GenericSetup.interfaces.EXTENSION"
/>

</configure>
4 changes: 4 additions & 0 deletions ftw/copymovepatches/tests/profiles/default/types.xml
@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<object name="portal_types" meta_type="Plone Types Tool">
<object name="DXContainer" meta_type="Dexterity FTI"/>
</object>
16 changes: 16 additions & 0 deletions ftw/copymovepatches/tests/profiles/default/types/DXContainer.xml
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<object name="DXContainer"
meta_type="Dexterity FTI"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
i18n:domain="ftw.copymovepatches">

<property name="title">DXContainer</property>
<property name="global_allow">True</property>
<property name="filter_content_types">False</property>
<property name="klass">plone.dexterity.content.Container</property>
<property name="behaviors">
<element value="plone.app.dexterity.behaviors.metadata.IBasic" />
<element value="plone.app.content.interfaces.INameFromTitle" />
</property>

</object>
14 changes: 14 additions & 0 deletions ftw/copymovepatches/tests/test_dexterity_copy_flags.py
@@ -0,0 +1,14 @@
from ftw.builder import Builder
from ftw.builder import create
from ftw.copymovepatches.tests import FunctionalTestCase


class TestDexterityCopyFlags(FunctionalTestCase):

def test_copy_flags_are_set_on_copy(self):
self.grant('Manager')
container_ori = create(Builder('dx container'))
clipboard = self.portal.manage_copyObjects([container_ori.id])
self.portal.manage_pasteObjects(clipboard)
container_copy = self.portal.get('copy_of_' + container_ori.id)
self.assertEquals(1, getattr(container_copy, '_v_is_cp', None))
3 changes: 2 additions & 1 deletion setup.py
Expand Up @@ -47,8 +47,9 @@

install_requires=[
'setuptools',
'plone.dexterity',
'collective.monkeypatcher',
'plone.app.dexterity',
'plone.dexterity',
'Plone',
],

Expand Down

0 comments on commit 3df04c1

Please sign in to comment.