From 1862fdf5ac76a9cd9004aef57d7299713dbfa49b Mon Sep 17 00:00:00 2001
From: Vincent Pelletier <vincent@nexedi.com>
Date: Thu, 6 Feb 2020 17:49:28 +0900
Subject: [PATCH] ERP5Type.patches.CMFBTreeFolder: Fold patch onto
 ERP5Type.Core.Folder.

All ERP5UI-visible (hence needing to call allowedContentTypes) BTReeFolder2
instances should already inherit ERP5Type.Core.Folder, removing the need
for this monkey-patch.
---
 product/ERP5Type/Core/Folder.py            | 36 ++++++++++++++
 product/ERP5Type/ZopePatch.py              |  1 -
 product/ERP5Type/patches/CMFBTreeFolder.py | 58 ----------------------
 3 files changed, 36 insertions(+), 59 deletions(-)
 delete mode 100644 product/ERP5Type/patches/CMFBTreeFolder.py

diff --git a/product/ERP5Type/Core/Folder.py b/product/ERP5Type/Core/Folder.py
index 5594f1471e..1257b1890b 100644
--- a/product/ERP5Type/Core/Folder.py
+++ b/product/ERP5Type/Core/Folder.py
@@ -162,6 +162,42 @@ class FolderMixIn(ExtensionClass.Base):
   security = ClassSecurityInfo()
   security.declareObjectProtected(Permissions.AccessContentsInformation)
 
+  security.declarePublic('allowedContentTypes')
+  def allowedContentTypes(self):
+    """
+    List portal_types which can be added in this folder / object.
+    """
+    portal_types = self.getPortalObject().portal_types
+    myType = portal_types.getTypeInfo(self)
+    if myType is not None:
+      if myType.filter_content_types:
+        # Iterate over allowed content types to avoid going over all portal
+        # types and retaining only a fraction.
+        result = []
+        for portal_type in myType.getTypeAllowedContentTypeList():
+          contentType = portal_types.getTypeInfo(portal_type)
+          if contentType is None:
+            raise AttributeError(
+              "Portal type '%s' does not exist and should not be allowed in '%s'" % (
+                portal_type,
+                self.getPortalType(),
+              ),
+            )
+          result.append(contentType)
+      else:
+        result = [
+          contentType
+          for contentType in portal_types.listTypeInfo(self)
+          if myType.allowType(contentType.getId())
+        ]
+    else:
+      result = portal_types.listTypeInfo()
+    return [
+      x
+      for x in result
+      if x.isConstructionAllowed(self)
+    ]
+
   security.declarePublic('newContent')
   def newContent(self, id=None, portal_type=None, id_group=None,
           default=None, method=None, container=None, temp_object=0, **kw):
diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py
index cf2e5e2b7b..e939461dd5 100644
--- a/product/ERP5Type/ZopePatch.py
+++ b/product/ERP5Type/ZopePatch.py
@@ -51,7 +51,6 @@ from Products.ERP5Type.patches import CookieCrumbler
 from Products.ERP5Type.patches import PropertySheets
 from Products.ERP5Type.patches import CMFCoreSkinnable
 from Products.ERP5Type.patches import CMFCoreSkinsTool
-from Products.ERP5Type.patches import CMFBTreeFolder
 from Products.ERP5Type.patches import OFSFile
 from Products.ERP5Type.patches import OFSFolder
 from Products.ERP5Type.patches import OFSUninstalled
diff --git a/product/ERP5Type/patches/CMFBTreeFolder.py b/product/ERP5Type/patches/CMFBTreeFolder.py
deleted file mode 100644
index 6162af7af6..0000000000
--- a/product/ERP5Type/patches/CMFBTreeFolder.py
+++ /dev/null
@@ -1,58 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
-# Copyright (c) 2006 Nexedi SARL and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-#from Products.CMFCore.PortalFolder import PortalFolder
-try:
-  from Products.CMFCore.CMFBTreeFolder import CMFBTreeFolder
-except ImportError:
-  from Products.BTreeFolder2.CMFBTreeFolder import CMFBTreeFolder
-
-"""
-  This patch tries to give only portal types that are defined
-  in the allowed content types field. This will make the
-  speed of allowed content type in almost O(1) instead of O(n),
-  where n is the number of portal types in types tool.
-"""
-
-def CMFBTreeFolder_allowedContentTypes(self):
-  """
-      List type info objects for types which can be added in
-      this folder.
-  """
-  result = []
-  portal_types = self.getPortalObject().portal_types
-  myType = portal_types.getTypeInfo(self)
-
-  if myType is not None:
-    allowed_types_to_check = []
-    if myType.filter_content_types:
-      for portal_type in myType.getTypeAllowedContentTypeList():
-        contentType = portal_types.getTypeInfo(portal_type)
-        if contentType is None:
-          raise AttributeError, "Portal type '%s' does not exist " \
-                                "and should not be allowed in '%s'" % \
-                                (portal_type, self.getPortalType())
-        result.append(contentType)
-    else:
-      for contentType in portal_types.listTypeInfo(self):
-        if myType.allowType(contentType.getId()):
-          result.append(contentType)
-  else:
-      result = portal_types.listTypeInfo()
-
-  return filter(
-      lambda typ, container=self: typ.isConstructionAllowed(container),
-      result)
-
-CMFBTreeFolder.allowedContentTypes = CMFBTreeFolder_allowedContentTypes
-- 
2.30.9