Repository: plone/Products.CMFPlone

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.


Discussion:
My suspect is that this function is obsolete and not used anymore (since quite a long time).
The fix is simple:
```
languages.sort(key lambda language: language[1])
```
instead of:
```
languages.sort(lambda x, y: cmp(x[1], y[1]))
```
but maybe we can just remove it completely because this is broken since we migrated to Python3 and (AFAIK) nobody complained.
Or should we deprecate it in Plone 5.2 and remove it in Plone 6?

Resolving patch:
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 @@ def manage_beforeDelete(self, container, item):
         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 @@ def view(self):
         """
         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 @@ def folderlistingFolderContents(self, contentFilter=None):
         """
         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


Test patch: