We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix or remove language
I was checking the code
https://github.com/plone/Products.CMFPlone/blob/36a66a82d8ff975148634626a70fd8b01f7e95b9/Products/CMFPlone/Portal.py#L150-L157

`cmp` should not be used because it was removed in Python3.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `Products/CMFPlone/Portal.py`
Content:
```
1 from AccessControl import ClassSecurityInfo
2 from AccessControl import Unauthorized
3 from AccessControl.class_init import InitializeClass
4 from Acquisition import aq_base
5 from ComputedAttribute import ComputedAttribute
6 from five.localsitemanager.registry import PersistentComponents
7 from OFS.ObjectManager import REPLACEABLE
8 from plone.dexterity.content import Container
9 from plone.i18n.locales.interfaces import IMetadataLanguageAvailability
10 from Products.CMFCore import permissions
11 from Products.CMFCore.interfaces import IContentish
12 from Products.CMFCore.interfaces import ISiteRoot
13 from Products.CMFCore.permissions import AccessContentsInformation
14 from Products.CMFCore.permissions import AddPortalMember
15 from Products.CMFCore.permissions import MailForgottenPassword
16 from Products.CMFCore.permissions import RequestReview
17 from Products.CMFCore.permissions import ReviewPortalContent
18 from Products.CMFCore.permissions import SetOwnPassword
19 from Products.CMFCore.permissions import SetOwnProperties
20 from Products.CMFCore.PortalFolder import PortalFolderBase
21 from Products.CMFCore.PortalObject import PortalObjectBase
22 from Products.CMFCore.Skinnable import SkinnableObjectManager
23 from Products.CMFCore.utils import _checkPermission
24 from Products.CMFCore.utils import getToolByName
25 from Products.CMFCore.utils import UniqueObject
26 from Products.CMFPlone import bbb
27 from Products.CMFPlone import PloneMessageFactory as _
28 from Products.CMFPlone.interfaces.siteroot import IPloneSiteRoot
29 from Products.CMFPlone.interfaces.syndication import ISyndicatable
30 from Products.CMFPlone.permissions import AddPortalContent
31 from Products.CMFPlone.permissions import AddPortalFolders
32 from Products.CMFPlone.permissions import ListPortalMembers
33 from Products.CMFPlone.permissions import ModifyPortalContent
34 from Products.CMFPlone.permissions import ReplyToItem
35 from Products.CMFPlone.permissions import View
36 from Products.Five.component.interfaces import IObjectManagerSite
37 from zope.component import queryUtility
38 from zope.interface.interfaces import ComponentLookupError
39 from zope.event import notify
40 from zope.interface import classImplementsOnly
41 from zope.interface import implementedBy
42 from zope.interface import implementer
43 from zope.traversing.interfaces import BeforeTraverseEvent
44 
45 
46 if bbb.HAS_ZSERVER:
47     from webdav.NullResource import NullResource
48 
49 
50 @implementer(IPloneSiteRoot, ISiteRoot, ISyndicatable, IObjectManagerSite)
51 class PloneSite(Container, SkinnableObjectManager, UniqueObject):
52     """ The Plone site object. """
53 
54     security = ClassSecurityInfo()
55     meta_type = portal_type = 'Plone Site'
56 
57     # Ensure certain attributes come from the correct base class.
58     _checkId = SkinnableObjectManager._checkId
59     manage_main = PortalFolderBase.manage_main
60 
61     def __getattr__(self, name):
62         try:
63             # Try DX
64             return super().__getattr__(name)
65         except AttributeError:
66             # Check portal_skins
67             return SkinnableObjectManager.__getattr__(self, name)
68 
69     def __setattr__(self, name, obj):
70         # handle re setting an item as an attribute
71         if self._tree is not None and name in self:
72             del self[name]
73             self[name] = obj
74         else:
75             super().__setattr__(name, obj)
76 
77     def __delattr__(self, name):
78         try:
79             return super().__delattr__(name)
80         except AttributeError:
81             return self.__delitem__(name)
82 
83     # Removes the 'Components Folder'
84 
85     manage_options = (
86         Container.manage_options[:2] +
87         Container.manage_options[3:])
88 
89     __ac_permissions__ = (
90         (AccessContentsInformation, ()),
91         (AddPortalMember, ()),
92         (SetOwnPassword, ()),
93         (SetOwnProperties, ()),
94         (MailForgottenPassword, ()),
95         (RequestReview, ()),
96         (ReviewPortalContent, ()),
97         (AddPortalContent, ()),
98         (AddPortalFolders, ()),
99         (ListPortalMembers, ()),
100         (ReplyToItem, ()),
101         (View, ('isEffective',)),
102         (ModifyPortalContent, ('manage_cutObjects', 'manage_pasteObjects',
103                                'manage_renameForm', 'manage_renameObject',
104                                'manage_renameObjects')))
105 
106     # Switch off ZMI ordering interface as it assumes a slightly
107     # different functionality
108     has_order_support = 0
109     management_page_charset = 'utf-8'
110     _default_sort_key = 'id'
111     _properties = (
112         {'id': 'title', 'type': 'string', 'mode': 'w'},
113         {'id': 'description', 'type': 'text', 'mode': 'w'},
114     )
115     title = ''
116     description = ''
117     icon = 'misc_/CMFPlone/tool.gif'
118 
119     # From PortalObjectBase
120     def __init__(self, id, title=''):
121         super(PloneSite, self).__init__(id, title=title)
122         components = PersistentComponents('++etc++site')
123         components.__parent__ = self
124         self.setSiteManager(components)
125 
126     # From PortalObjectBase
127     def __before_publishing_traverse__(self, arg1, arg2=None):
128         """ Pre-traversal hook.
129         """
130         # XXX hack around a bug(?) in BeforeTraverse.MultiHook
131         REQUEST = arg2 or arg1
132 
133         try:
134             notify(BeforeTraverseEvent(self, REQUEST))
135         except ComponentLookupError:
136             # allow ZMI access, even if the portal's site manager is missing
137             pass
138         self.setupCurrentSkin(REQUEST)
139 
140         super(PloneSite, self).__before_publishing_traverse__(arg1, arg2)
141 
142     def __browser_default__(self, request):
143         """ Set default so we can return whatever we want instead
144         of index_html """
145         return getToolByName(self, 'plone_utils').browserDefault(self)
146 
147     def index_html(self):
148         """ Acquire if not present. """
149         request = getattr(self, 'REQUEST', None)
150         if (
151             request is not None
152             and 'REQUEST_METHOD' in request
153             and request.maybe_webdav_client
154         ):
155             method = request['REQUEST_METHOD']
156             if bbb.HAS_ZSERVER and method in ('PUT', ):
157                 # Very likely a WebDAV client trying to create something
158                 result = NullResource(self, 'index_html')
159                 setattr(result, '__replaceable__', REPLACEABLE)
160                 return result
161             elif method not in ('GET', 'HEAD', 'POST'):
162                 raise AttributeError('index_html')
163         # Acquire from skin.
164         _target = self.__getattr__('index_html')
165         result = aq_base(_target).__of__(self)
166         setattr(result, '__replaceable__', REPLACEABLE)
167         return result
168 
169     index_html = ComputedAttribute(index_html, 1)
170 
171     def manage_beforeDelete(self, container, item):
172         # Should send out an Event before Site is being deleted.
173         self.removal_inprogress = 1
174         PloneSite.inheritedAttribute('manage_beforeDelete')(self, container,
175                                                             item)
176 
177     security.declareProtected(permissions.DeleteObjects, 'manage_delObjects')
178 
179     def manage_delObjects(self, ids=None, REQUEST=None):
180         """We need to enforce security."""
181         if ids is None:
182             ids = []
183         if isinstance(ids, str):
184             ids = [ids]
185         for id in ids:
186             item = self._getOb(id)
187             if not _checkPermission(permissions.DeleteObjects, item):
188                 raise Unauthorized(
189                     "Do not have permissions to remove this object")
190         return PortalObjectBase.manage_delObjects(self, ids, REQUEST=REQUEST)
191 
192     def view(self):
193         """ Ensure that we get a plain view of the object, via a delegation to
194         __call__(), which is defined in BrowserDefaultMixin
195         """
196         return self()
197 
198     security.declareProtected(permissions.AccessContentsInformation,
199                               'folderlistingFolderContents')
200 
201     def folderlistingFolderContents(self, contentFilter=None):
202         """Calls listFolderContents in protected only by ACI so that
203         folder_listing can work without the List folder contents permission.
204 
205         This is copied from Archetypes Basefolder and is needed by the
206         reference browser.
207         """
208         return self.listFolderContents(contentFilter)
209 
210     security.declarePublic('availableLanguages')
211 
212     def availableLanguages(self):
213         util = queryUtility(IMetadataLanguageAvailability)
214         languages = util.getLanguageListing()
215         languages.sort(lambda x, y: cmp(x[1], y[1]))
216         # Put language neutral at the top.
217         languages.insert(0, ('', _('Language neutral (site default)')))
218 
219         return languages
220 
221     def isEffective(self, date):
222         # Override DefaultDublinCoreImpl's test, since we are always viewable.
223         return 1
224 
225 
226 # Remove the IContentish interface so we don't listen to events that won't
227 # apply to the site root, ie handleUidAnnotationEvent
228 classImplementsOnly(PloneSite, implementedBy(PloneSite) - IContentish)
229 
230 InitializeClass(PloneSite)
231
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/Products/CMFPlone/Portal.py b/Products/CMFPlone/Portal.py
--- a/Products/CMFPlone/Portal.py
+++ b/Products/CMFPlone/Portal.py
@@ -6,7 +6,6 @@
 from five.localsitemanager.registry import PersistentComponents
 from OFS.ObjectManager import REPLACEABLE
 from plone.dexterity.content import Container
-from plone.i18n.locales.interfaces import IMetadataLanguageAvailability
 from Products.CMFCore import permissions
 from Products.CMFCore.interfaces import IContentish
 from Products.CMFCore.interfaces import ISiteRoot
@@ -34,7 +33,6 @@
 from Products.CMFPlone.permissions import ReplyToItem
 from Products.CMFPlone.permissions import View
 from Products.Five.component.interfaces import IObjectManagerSite
-from zope.component import queryUtility
 from zope.interface.interfaces import ComponentLookupError
 from zope.event import notify
 from zope.interface import classImplementsOnly
@@ -174,8 +172,7 @@
         PloneSite.inheritedAttribute('manage_beforeDelete')(self, container,
                                                             item)
 
-    security.declareProtected(permissions.DeleteObjects, 'manage_delObjects')
-
+    @security.protected(permissions.DeleteObjects)
     def manage_delObjects(self, ids=None, REQUEST=None):
         """We need to enforce security."""
         if ids is None:
@@ -195,9 +192,7 @@
         """
         return self()
 
-    security.declareProtected(permissions.AccessContentsInformation,
-                              'folderlistingFolderContents')
-
+    @security.protected(permissions.AccessContentsInformation)
     def folderlistingFolderContents(self, contentFilter=None):
         """Calls listFolderContents in protected only by ACI so that
         folder_listing can work without the List folder contents permission.
@@ -207,17 +202,6 @@
         """
         return self.listFolderContents(contentFilter)
 
-    security.declarePublic('availableLanguages')
-
-    def availableLanguages(self):
-        util = queryUtility(IMetadataLanguageAvailability)
-        languages = util.getLanguageListing()
-        languages.sort(lambda x, y: cmp(x[1], y[1]))
-        # Put language neutral at the top.
-        languages.insert(0, ('', _('Language neutral (site default)')))
-
-        return languages
-
     def isEffective(self, date):
         # Override DefaultDublinCoreImpl's test, since we are always viewable.
         return 1

{"golden_diff": "diff --git a/Products/CMFPlone/Portal.py b/Products/CMFPlone/Portal.py\n--- a/Products/CMFPlone/Portal.py\n+++ b/Products/CMFPlone/Portal.py\n@@ -6,7 +6,6 @@\n from five.localsitemanager.registry import PersistentComponents\n from OFS.ObjectManager import REPLACEABLE\n from plone.dexterity.content import Container\n-from plone.i18n.locales.interfaces import IMetadataLanguageAvailability\n from Products.CMFCore import permissions\n from Products.CMFCore.interfaces import IContentish\n from Products.CMFCore.interfaces import ISiteRoot\n@@ -34,7 +33,6 @@\n from Products.CMFPlone.permissions import ReplyToItem\n from Products.CMFPlone.permissions import View\n from Products.Five.component.interfaces import IObjectManagerSite\n-from zope.component import queryUtility\n from zope.interface.interfaces import ComponentLookupError\n from zope.event import notify\n from zope.interface import classImplementsOnly\n@@ -174,8 +172,7 @@\n         PloneSite.inheritedAttribute('manage_beforeDelete')(self, container,\n                                                             item)\n \n-    security.declareProtected(permissions.DeleteObjects, 'manage_delObjects')\n-\n+    @security.protected(permissions.DeleteObjects)\n     def manage_delObjects(self, ids=None, REQUEST=None):\n         \"\"\"We need to enforce security.\"\"\"\n         if ids is None:\n@@ -195,9 +192,7 @@\n         \"\"\"\n         return self()\n \n-    security.declareProtected(permissions.AccessContentsInformation,\n-                              'folderlistingFolderContents')\n-\n+    @security.protected(permissions.AccessContentsInformation)\n     def folderlistingFolderContents(self, contentFilter=None):\n         \"\"\"Calls listFolderContents in protected only by ACI so that\n         folder_listing can work without the List folder contents permission.\n@@ -207,17 +202,6 @@\n         \"\"\"\n         return self.listFolderContents(contentFilter)\n \n-    security.declarePublic('availableLanguages')\n-\n-    def availableLanguages(self):\n-        util = queryUtility(IMetadataLanguageAvailability)\n-        languages = util.getLanguageListing()\n-        languages.sort(lambda x, y: cmp(x[1], y[1]))\n-        # Put language neutral at the top.\n-        languages.insert(0, ('', _('Language neutral (site default)')))\n-\n-        return languages\n-\n     def isEffective(self, date):\n         # Override DefaultDublinCoreImpl's test, since we are always viewable.\n         return 1\n", "issue": "Fix or remove language\nI was checking the code\r\nhttps://github.com/plone/Products.CMFPlone/blob/36a66a82d8ff975148634626a70fd8b01f7e95b9/Products/CMFPlone/Portal.py#L150-L157\r\n\r\n`cmp` should not be used because it was removed in Python3.\n", "before_files": [{"content": "from AccessControl import ClassSecurityInfo\nfrom AccessControl import Unauthorized\nfrom AccessControl.class_init import InitializeClass\nfrom Acquisition import aq_base\nfrom ComputedAttribute import ComputedAttribute\nfrom five.localsitemanager.registry import PersistentComponents\nfrom OFS.ObjectManager import REPLACEABLE\nfrom plone.dexterity.content import Container\nfrom plone.i18n.locales.interfaces import IMetadataLanguageAvailability\nfrom Products.CMFCore import permissions\nfrom Products.CMFCore.interfaces import IContentish\nfrom Products.CMFCore.interfaces import ISiteRoot\nfrom Products.CMFCore.permissions import AccessContentsInformation\nfrom Products.CMFCore.permissions import AddPortalMember\nfrom Products.CMFCore.permissions import MailForgottenPassword\nfrom Products.CMFCore.permissions import RequestReview\nfrom Products.CMFCore.permissions import ReviewPortalContent\nfrom Products.CMFCore.permissions import SetOwnPassword\nfrom Products.CMFCore.permissions import SetOwnProperties\nfrom Products.CMFCore.PortalFolder import PortalFolderBase\nfrom Products.CMFCore.PortalObject import PortalObjectBase\nfrom Products.CMFCore.Skinnable import SkinnableObjectManager\nfrom Products.CMFCore.utils import _checkPermission\nfrom Products.CMFCore.utils import getToolByName\nfrom Products.CMFCore.utils import UniqueObject\nfrom Products.CMFPlone import bbb\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.interfaces.siteroot import IPloneSiteRoot\nfrom Products.CMFPlone.interfaces.syndication import ISyndicatable\nfrom Products.CMFPlone.permissions import AddPortalContent\nfrom Products.CMFPlone.permissions import AddPortalFolders\nfrom Products.CMFPlone.permissions import ListPortalMembers\nfrom Products.CMFPlone.permissions import ModifyPortalContent\nfrom Products.CMFPlone.permissions import ReplyToItem\nfrom Products.CMFPlone.permissions import View\nfrom Products.Five.component.interfaces import IObjectManagerSite\nfrom zope.component import queryUtility\nfrom zope.interface.interfaces import ComponentLookupError\nfrom zope.event import notify\nfrom zope.interface import classImplementsOnly\nfrom zope.interface import implementedBy\nfrom zope.interface import implementer\nfrom zope.traversing.interfaces import BeforeTraverseEvent\n\n\nif bbb.HAS_ZSERVER:\n    from webdav.NullResource import NullResource\n\n\n@implementer(IPloneSiteRoot, ISiteRoot, ISyndicatable, IObjectManagerSite)\nclass PloneSite(Container, SkinnableObjectManager, UniqueObject):\n    \"\"\" The Plone site object. \"\"\"\n\n    security = ClassSecurityInfo()\n    meta_type = portal_type = 'Plone Site'\n\n    # Ensure certain attributes come from the correct base class.\n    _checkId = SkinnableObjectManager._checkId\n    manage_main = PortalFolderBase.manage_main\n\n    def __getattr__(self, name):\n        try:\n            # Try DX\n            return super().__getattr__(name)\n        except AttributeError:\n            # Check portal_skins\n            return SkinnableObjectManager.__getattr__(self, name)\n\n    def __setattr__(self, name, obj):\n        # handle re setting an item as an attribute\n        if self._tree is not None and name in self:\n            del self[name]\n            self[name] = obj\n        else:\n            super().__setattr__(name, obj)\n\n    def __delattr__(self, name):\n        try:\n            return super().__delattr__(name)\n        except AttributeError:\n            return self.__delitem__(name)\n\n    # Removes the 'Components Folder'\n\n    manage_options = (\n        Container.manage_options[:2] +\n        Container.manage_options[3:])\n\n    __ac_permissions__ = (\n        (AccessContentsInformation, ()),\n        (AddPortalMember, ()),\n        (SetOwnPassword, ()),\n        (SetOwnProperties, ()),\n        (MailForgottenPassword, ()),\n        (RequestReview, ()),\n        (ReviewPortalContent, ()),\n        (AddPortalContent, ()),\n        (AddPortalFolders, ()),\n        (ListPortalMembers, ()),\n        (ReplyToItem, ()),\n        (View, ('isEffective',)),\n        (ModifyPortalContent, ('manage_cutObjects', 'manage_pasteObjects',\n                               'manage_renameForm', 'manage_renameObject',\n                               'manage_renameObjects')))\n\n    # Switch off ZMI ordering interface as it assumes a slightly\n    # different functionality\n    has_order_support = 0\n    management_page_charset = 'utf-8'\n    _default_sort_key = 'id'\n    _properties = (\n        {'id': 'title', 'type': 'string', 'mode': 'w'},\n        {'id': 'description', 'type': 'text', 'mode': 'w'},\n    )\n    title = ''\n    description = ''\n    icon = 'misc_/CMFPlone/tool.gif'\n\n    # From PortalObjectBase\n    def __init__(self, id, title=''):\n        super(PloneSite, self).__init__(id, title=title)\n        components = PersistentComponents('++etc++site')\n        components.__parent__ = self\n        self.setSiteManager(components)\n\n    # From PortalObjectBase\n    def __before_publishing_traverse__(self, arg1, arg2=None):\n        \"\"\" Pre-traversal hook.\n        \"\"\"\n        # XXX hack around a bug(?) in BeforeTraverse.MultiHook\n        REQUEST = arg2 or arg1\n\n        try:\n            notify(BeforeTraverseEvent(self, REQUEST))\n        except ComponentLookupError:\n            # allow ZMI access, even if the portal's site manager is missing\n            pass\n        self.setupCurrentSkin(REQUEST)\n\n        super(PloneSite, self).__before_publishing_traverse__(arg1, arg2)\n\n    def __browser_default__(self, request):\n        \"\"\" Set default so we can return whatever we want instead\n        of index_html \"\"\"\n        return getToolByName(self, 'plone_utils').browserDefault(self)\n\n    def index_html(self):\n        \"\"\" Acquire if not present. \"\"\"\n        request = getattr(self, 'REQUEST', None)\n        if (\n            request is not None\n            and 'REQUEST_METHOD' in request\n            and request.maybe_webdav_client\n        ):\n            method = request['REQUEST_METHOD']\n            if bbb.HAS_ZSERVER and method in ('PUT', ):\n                # Very likely a WebDAV client trying to create something\n                result = NullResource(self, 'index_html')\n                setattr(result, '__replaceable__', REPLACEABLE)\n                return result\n            elif method not in ('GET', 'HEAD', 'POST'):\n                raise AttributeError('index_html')\n        # Acquire from skin.\n        _target = self.__getattr__('index_html')\n        result = aq_base(_target).__of__(self)\n        setattr(result, '__replaceable__', REPLACEABLE)\n        return result\n\n    index_html = ComputedAttribute(index_html, 1)\n\n    def manage_beforeDelete(self, container, item):\n        # Should send out an Event before Site is being deleted.\n        self.removal_inprogress = 1\n        PloneSite.inheritedAttribute('manage_beforeDelete')(self, container,\n                                                            item)\n\n    security.declareProtected(permissions.DeleteObjects, 'manage_delObjects')\n\n    def manage_delObjects(self, ids=None, REQUEST=None):\n        \"\"\"We need to enforce security.\"\"\"\n        if ids is None:\n            ids = []\n        if isinstance(ids, str):\n            ids = [ids]\n        for id in ids:\n            item = self._getOb(id)\n            if not _checkPermission(permissions.DeleteObjects, item):\n                raise Unauthorized(\n                    \"Do not have permissions to remove this object\")\n        return PortalObjectBase.manage_delObjects(self, ids, REQUEST=REQUEST)\n\n    def view(self):\n        \"\"\" Ensure that we get a plain view of the object, via a delegation to\n        __call__(), which is defined in BrowserDefaultMixin\n        \"\"\"\n        return self()\n\n    security.declareProtected(permissions.AccessContentsInformation,\n                              'folderlistingFolderContents')\n\n    def folderlistingFolderContents(self, contentFilter=None):\n        \"\"\"Calls listFolderContents in protected only by ACI so that\n        folder_listing can work without the List folder contents permission.\n\n        This is copied from Archetypes Basefolder and is needed by the\n        reference browser.\n        \"\"\"\n        return self.listFolderContents(contentFilter)\n\n    security.declarePublic('availableLanguages')\n\n    def availableLanguages(self):\n        util = queryUtility(IMetadataLanguageAvailability)\n        languages = util.getLanguageListing()\n        languages.sort(lambda x, y: cmp(x[1], y[1]))\n        # Put language neutral at the top.\n        languages.insert(0, ('', _('Language neutral (site default)')))\n\n        return languages\n\n    def isEffective(self, date):\n        # Override DefaultDublinCoreImpl's test, since we are always viewable.\n        return 1\n\n\n# Remove the IContentish interface so we don't listen to events that won't\n# apply to the site root, ie handleUidAnnotationEvent\nclassImplementsOnly(PloneSite, implementedBy(PloneSite) - IContentish)\n\nInitializeClass(PloneSite)\n", "path": "Products/CMFPlone/Portal.py"}], "after_files": [{"content": "from AccessControl import ClassSecurityInfo\nfrom AccessControl import Unauthorized\nfrom AccessControl.class_init import InitializeClass\nfrom Acquisition import aq_base\nfrom ComputedAttribute import ComputedAttribute\nfrom five.localsitemanager.registry import PersistentComponents\nfrom OFS.ObjectManager import REPLACEABLE\nfrom plone.dexterity.content import Container\nfrom Products.CMFCore import permissions\nfrom Products.CMFCore.interfaces import IContentish\nfrom Products.CMFCore.interfaces import ISiteRoot\nfrom Products.CMFCore.permissions import AccessContentsInformation\nfrom Products.CMFCore.permissions import AddPortalMember\nfrom Products.CMFCore.permissions import MailForgottenPassword\nfrom Products.CMFCore.permissions import RequestReview\nfrom Products.CMFCore.permissions import ReviewPortalContent\nfrom Products.CMFCore.permissions import SetOwnPassword\nfrom Products.CMFCore.permissions import SetOwnProperties\nfrom Products.CMFCore.PortalFolder import PortalFolderBase\nfrom Products.CMFCore.PortalObject import PortalObjectBase\nfrom Products.CMFCore.Skinnable import SkinnableObjectManager\nfrom Products.CMFCore.utils import _checkPermission\nfrom Products.CMFCore.utils import getToolByName\nfrom Products.CMFCore.utils import UniqueObject\nfrom Products.CMFPlone import bbb\nfrom Products.CMFPlone import PloneMessageFactory as _\nfrom Products.CMFPlone.interfaces.siteroot import IPloneSiteRoot\nfrom Products.CMFPlone.interfaces.syndication import ISyndicatable\nfrom Products.CMFPlone.permissions import AddPortalContent\nfrom Products.CMFPlone.permissions import AddPortalFolders\nfrom Products.CMFPlone.permissions import ListPortalMembers\nfrom Products.CMFPlone.permissions import ModifyPortalContent\nfrom Products.CMFPlone.permissions import ReplyToItem\nfrom Products.CMFPlone.permissions import View\nfrom Products.Five.component.interfaces import IObjectManagerSite\nfrom zope.interface.interfaces import ComponentLookupError\nfrom zope.event import notify\nfrom zope.interface import classImplementsOnly\nfrom zope.interface import implementedBy\nfrom zope.interface import implementer\nfrom zope.traversing.interfaces import BeforeTraverseEvent\n\n\nif bbb.HAS_ZSERVER:\n    from webdav.NullResource import NullResource\n\n\n@implementer(IPloneSiteRoot, ISiteRoot, ISyndicatable, IObjectManagerSite)\nclass PloneSite(Container, SkinnableObjectManager, UniqueObject):\n    \"\"\" The Plone site object. \"\"\"\n\n    security = ClassSecurityInfo()\n    meta_type = portal_type = 'Plone Site'\n\n    # Ensure certain attributes come from the correct base class.\n    _checkId = SkinnableObjectManager._checkId\n    manage_main = PortalFolderBase.manage_main\n\n    def __getattr__(self, name):\n        try:\n            # Try DX\n            return super().__getattr__(name)\n        except AttributeError:\n            # Check portal_skins\n            return SkinnableObjectManager.__getattr__(self, name)\n\n    def __setattr__(self, name, obj):\n        # handle re setting an item as an attribute\n        if self._tree is not None and name in self:\n            del self[name]\n            self[name] = obj\n        else:\n            super().__setattr__(name, obj)\n\n    def __delattr__(self, name):\n        try:\n            return super().__delattr__(name)\n        except AttributeError:\n            return self.__delitem__(name)\n\n    # Removes the 'Components Folder'\n\n    manage_options = (\n        Container.manage_options[:2] +\n        Container.manage_options[3:])\n\n    __ac_permissions__ = (\n        (AccessContentsInformation, ()),\n        (AddPortalMember, ()),\n        (SetOwnPassword, ()),\n        (SetOwnProperties, ()),\n        (MailForgottenPassword, ()),\n        (RequestReview, ()),\n        (ReviewPortalContent, ()),\n        (AddPortalContent, ()),\n        (AddPortalFolders, ()),\n        (ListPortalMembers, ()),\n        (ReplyToItem, ()),\n        (View, ('isEffective',)),\n        (ModifyPortalContent, ('manage_cutObjects', 'manage_pasteObjects',\n                               'manage_renameForm', 'manage_renameObject',\n                               'manage_renameObjects')))\n\n    # Switch off ZMI ordering interface as it assumes a slightly\n    # different functionality\n    has_order_support = 0\n    management_page_charset = 'utf-8'\n    _default_sort_key = 'id'\n    _properties = (\n        {'id': 'title', 'type': 'string', 'mode': 'w'},\n        {'id': 'description', 'type': 'text', 'mode': 'w'},\n    )\n    title = ''\n    description = ''\n    icon = 'misc_/CMFPlone/tool.gif'\n\n    # From PortalObjectBase\n    def __init__(self, id, title=''):\n        super(PloneSite, self).__init__(id, title=title)\n        components = PersistentComponents('++etc++site')\n        components.__parent__ = self\n        self.setSiteManager(components)\n\n    # From PortalObjectBase\n    def __before_publishing_traverse__(self, arg1, arg2=None):\n        \"\"\" Pre-traversal hook.\n        \"\"\"\n        # XXX hack around a bug(?) in BeforeTraverse.MultiHook\n        REQUEST = arg2 or arg1\n\n        try:\n            notify(BeforeTraverseEvent(self, REQUEST))\n        except ComponentLookupError:\n            # allow ZMI access, even if the portal's site manager is missing\n            pass\n        self.setupCurrentSkin(REQUEST)\n\n        super(PloneSite, self).__before_publishing_traverse__(arg1, arg2)\n\n    def __browser_default__(self, request):\n        \"\"\" Set default so we can return whatever we want instead\n        of index_html \"\"\"\n        return getToolByName(self, 'plone_utils').browserDefault(self)\n\n    def index_html(self):\n        \"\"\" Acquire if not present. \"\"\"\n        request = getattr(self, 'REQUEST', None)\n        if (\n            request is not None\n            and 'REQUEST_METHOD' in request\n            and request.maybe_webdav_client\n        ):\n            method = request['REQUEST_METHOD']\n            if bbb.HAS_ZSERVER and method in ('PUT', ):\n                # Very likely a WebDAV client trying to create something\n                result = NullResource(self, 'index_html')\n                setattr(result, '__replaceable__', REPLACEABLE)\n                return result\n            elif method not in ('GET', 'HEAD', 'POST'):\n                raise AttributeError('index_html')\n        # Acquire from skin.\n        _target = self.__getattr__('index_html')\n        result = aq_base(_target).__of__(self)\n        setattr(result, '__replaceable__', REPLACEABLE)\n        return result\n\n    index_html = ComputedAttribute(index_html, 1)\n\n    def manage_beforeDelete(self, container, item):\n        # Should send out an Event before Site is being deleted.\n        self.removal_inprogress = 1\n        PloneSite.inheritedAttribute('manage_beforeDelete')(self, container,\n                                                            item)\n\n    @security.protected(permissions.DeleteObjects)\n    def manage_delObjects(self, ids=None, REQUEST=None):\n        \"\"\"We need to enforce security.\"\"\"\n        if ids is None:\n            ids = []\n        if isinstance(ids, str):\n            ids = [ids]\n        for id in ids:\n            item = self._getOb(id)\n            if not _checkPermission(permissions.DeleteObjects, item):\n                raise Unauthorized(\n                    \"Do not have permissions to remove this object\")\n        return PortalObjectBase.manage_delObjects(self, ids, REQUEST=REQUEST)\n\n    def view(self):\n        \"\"\" Ensure that we get a plain view of the object, via a delegation to\n        __call__(), which is defined in BrowserDefaultMixin\n        \"\"\"\n        return self()\n\n    @security.protected(permissions.AccessContentsInformation)\n    def folderlistingFolderContents(self, contentFilter=None):\n        \"\"\"Calls listFolderContents in protected only by ACI so that\n        folder_listing can work without the List folder contents permission.\n\n        This is copied from Archetypes Basefolder and is needed by the\n        reference browser.\n        \"\"\"\n        return self.listFolderContents(contentFilter)\n\n    def isEffective(self, date):\n        # Override DefaultDublinCoreImpl's test, since we are always viewable.\n        return 1\n\n\n# Remove the IContentish interface so we don't listen to events that won't\n# apply to the site root, ie handleUidAnnotationEvent\nclassImplementsOnly(PloneSite, implementedBy(PloneSite) - IContentish)\n\nInitializeClass(PloneSite)\n", "path": "Products/CMFPlone/Portal.py"}]}