internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: plone/Products.CMFPlone

Issue:
Plone 6: the Plone site should land in portal catalog
At the moment the Plone site is not cataloged.
After PLIP #2454 we do not have any more a front page.
Instead we can enter some text in the Plone site.
I think that when searching for that text, the Plone site should be returned among the results.

### What version of Plone/ Addons I am using:

Plone 6



Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/CatalogTool.py b/Products/CMFPlone/CatalogTool.py
--- a/Products/CMFPlone/CatalogTool.py
+++ b/Products/CMFPlone/CatalogTool.py
@@ -488,6 +488,7 @@ def indexObject(obj, path):
                     pass
         self.manage_catalogClear()
         portal = aq_parent(aq_inner(self))
+        indexObject(portal, '')
         portal.ZopeFindAndApply(
             portal,
             search_sub=True,
diff --git a/Products/CMFPlone/Portal.py b/Products/CMFPlone/Portal.py
--- a/Products/CMFPlone/Portal.py
+++ b/Products/CMFPlone/Portal.py
@@ -222,19 +222,6 @@ def isEffective(self, date):
         # Override DefaultDublinCoreImpl's test, since we are always viewable.
         return 1
 
-    # Ensure portals don't get cataloged.
-    def indexObject(self):
-        pass
-
-    def unindexObject(self):
-        pass
-
-    def reindexObject(self, idxs=None):
-        pass
-
-    def reindexObjectSecurity(self, skip_self=False):
-        pass
-
 
 # Remove the IContentish interface so we don't listen to events that won't
 # apply to the site root, ie handleUidAnnotationEvent


Test patch:
diff --git a/Products/CMFPlone/tests/testCatalogTool.py b/Products/CMFPlone/tests/testCatalogTool.py
--- a/Products/CMFPlone/tests/testCatalogTool.py
+++ b/Products/CMFPlone/tests/testCatalogTool.py
@@ -31,7 +31,7 @@
 group2 = 'g2'
 
 base_content = ['Members', 'aggregator', 'aggregator',
-                'events', 'news', TEST_USER_ID, 'doc']
+                'events', 'news', 'plone', TEST_USER_ID, 'doc']
 
 
 class TestCatalogSetup(PloneTestCase):
diff --git a/Products/CMFPlone/tests/testPortalCreation.py b/Products/CMFPlone/tests/testPortalCreation.py
--- a/Products/CMFPlone/tests/testPortalCreation.py
+++ b/Products/CMFPlone/tests/testPortalCreation.py
@@ -86,6 +86,13 @@ def testWorkflowIsActionProvider(self):
             'portal_workflow' in self.actions.listActionProviders()
         )
 
+    def testPortalIsIndexed(self):
+        # The Plone site should be cataloged
+        res = self.catalog(getId="plone")
+        self.assertEqual(len(res), 1)
+        self.assertEqual(res[0].getId, "plone")
+        self.assertEqual(res[0].Title, "Welcome to Plone")
+
     def testMembersFolderMetaType(self):
         # Members folder should have meta_type 'Dexterity Container'
         members = self.membership.getMembersFolder()
Repository: plone/Products.CMFPlone

Issue:
relationhelpers have hard dependency on plone.app.iterate
The newly introduced relationhelpers are having `plone.app.iterate` as a hard dependency.

`plone.app.iterate` is a dependency of the `Plone` package, but not of `Products.CMFPlone`. See:

https://github.com/plone/Products.CMFPlone/blob/d07a74b6f7d944a08563c479c68c76fe6bd3b260/Products/CMFPlone/relationhelper.py#L4-L5

This need to be changed into a soft dependency at least.


Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/relationhelper.py b/Products/CMFPlone/relationhelper.py
--- a/Products/CMFPlone/relationhelper.py
+++ b/Products/CMFPlone/relationhelper.py
@@ -1,8 +1,6 @@
 from collections import Counter
 from collections import defaultdict
 from five.intid.intid import addIntIdSubscriber
-from plone.app.iterate.dexterity import ITERATE_RELATION_NAME
-from plone.app.iterate.dexterity.relation import StagingRelationValue
 from plone.app.linkintegrity.handlers import modifiedContent
 from plone.app.linkintegrity.utils import referencedRelationship
 from plone.app.relationfield.event import update_behavior_relations
@@ -26,6 +24,18 @@
 from zope.intid.interfaces import ObjectMissingError
 
 import logging
+import pkg_resources
+
+try:
+    # "iterate" is not a dependency of CMFPlone, but a consumer of it
+    pkg_resources.get_distribution("plone.app.iterate")
+except pkg_resources.DistributionNotFound:
+    HAS_ITERATE = False
+else:
+    HAS_ITERATE = True
+    from plone.app.iterate.dexterity import ITERATE_RELATION_NAME
+    from plone.app.iterate.dexterity.relation import StagingRelationValue
+
 
 logger = logging.getLogger(__name__)
 
@@ -183,7 +193,7 @@ def restore_relations(context=None, all_relations=None):
             update_linkintegrity.add(item['from_uuid'])
             continue
 
-        if from_attribute == ITERATE_RELATION_NAME:
+        if HAS_ITERATE and from_attribute == ITERATE_RELATION_NAME:
             # Iterate relations are not set as values of fields
             relation = StagingRelationValue(to_id)
             event._setRelation(source_obj, ITERATE_RELATION_NAME, relation)


Test patch:
Repository: plone/Products.CMFPlone

Issue:
DX-Site-Root: ZMI Nav-Tree is no longer expandable
After migrating to dx-site-root, the navtree within the zmi is no longer expandable

![Screenshot 2021-09-20 at 09 10 52](https://user-images.githubusercontent.com/365761/133967168-6a1b8f88-b8ca-4252-9d60-91ca842a0e3e.png)

https://github.com/plone/Products.CMFPlone/issues/2454 @jaroel @ale-rt 


Discussion:
I will have a look!

This is true for all dexterity.Container classes ... would be cool if the containers could expand in ZMI in general ... 
What a rabbit hole! Wanna feel like Alice? Go here https://github.com/zopefoundation/Zope/blob/master/src/App/dtml/menu.dtml and here https://github.com/zopefoundation/DocumentTemplate/blob/master/src/TreeDisplay/TreeTag.py
Need more mushrooms or tea....
Before you enable this by default, please keep in mind that BTreeFolder2 objects may contain many many many items ;)
For the site root we want it expandable. I doubt anyone adds there N-many items. And if: IDK 

Resolving patch:
diff --git a/Products/CMFPlone/Portal.py b/Products/CMFPlone/Portal.py
--- a/Products/CMFPlone/Portal.py
+++ b/Products/CMFPlone/Portal.py
@@ -137,6 +137,16 @@ def __before_publishing_traverse__(self, arg1, arg2=None):
 
         super(PloneSite, self).__before_publishing_traverse__(arg1, arg2)
 
+    # Concept from OFS.OrderSupport
+    @security.protected(permissions.AccessContentsInformation)
+    def tpValues(self):
+        # Return a list of subobjects, used by ZMI tree tag (and only there).
+        # see also https://github.com/plone/Products.CMFPlone/issues/3323
+        return sorted(
+            (obj for obj in self.objectValues() if getattr(aq_base(obj), 'isPrincipiaFolderish', False)),
+            key=lambda obj: obj.getId(),
+        )
+
     def __browser_default__(self, request):
         """ Set default so we can return whatever we want instead
         of index_html """


Test patch:
Repository: plone/Products.CMFPlone

Issue:
Expose the human_readable_size helper in the @@plone view
The [@@plone view](https://github.com/plone/Products.CMFPlone/blob/009f785e450430ee7b143624480aef9268491c0b/Products/CMFPlone/browser/ploneview.py#L19) has helper methods that can be used in templates.
It would be handy to add the [Products.CMFPlone.utils.human_readable_size](https://github.com/plone/Products.CMFPlone/blob/009f785e450430ee7b143624480aef9268491c0b/Products/CMFPlone/utils.py#L855-L876) function as a method of that view.


Discussion:
I do not think this addition should be a PLIP, what do you think?
CC @plone/framework-team 
it is a [well tested method](https://github.com/plone/Products.CMFPlone/blob/009f785e450430ee7b143624480aef9268491c0b/Products/CMFPlone/tests/test_utils.py#L149-L190) and [@@plone view](https://github.com/plone/Products.CMFPlone/blob/009f785e450430ee7b143624480aef9268491c0b/Products/CMFPlone/browser/ploneview.py#L19) placement looks handy for templates.

+1 on the addition, not so complex use case to need a PLIP also in my opinion.
FYI plone.app.content already use it in a template like this https://github.com/plone/plone.app.content/blob/61c3b9918d79451aeceed63969cde930c70e2cef/plone/app/content/browser/templates/content_status_history.pt#L126 and 
https://github.com/plone/plone.app.content/blob/61c3b9918d79451aeceed63969cde930c70e2cef/plone/app/content/browser/content_status_history.py#L157-L158

Resolving patch:
diff --git a/Products/CMFPlone/browser/ploneview.py b/Products/CMFPlone/browser/ploneview.py
--- a/Products/CMFPlone/browser/ploneview.py
+++ b/Products/CMFPlone/browser/ploneview.py
@@ -211,3 +211,7 @@ def patterns_settings(self):
         return getMultiAdapter(
             (context, self.request),
             name='plone_patterns_settings')()
+
+    @property
+    def human_readable_size(self):
+        return utils.human_readable_size


Test patch:
diff --git a/Products/CMFPlone/tests/testPloneView.py b/Products/CMFPlone/tests/testPloneView.py
--- a/Products/CMFPlone/tests/testPloneView.py
+++ b/Products/CMFPlone/tests/testPloneView.py
@@ -151,3 +151,8 @@ def testCropText(self):
     def testSiteEncoding(self):
         view = Plone(self.portal, self.app.REQUEST)
         self.assertEqual('utf-8', view.site_encoding())
+
+    def test_human_readable_size(self):
+        view = Plone(self.portal, self.app.REQUEST)
+        from Products.CMFPlone.utils import human_readable_size
+        self.assertIs(view.human_readable_size, human_readable_size)
Repository: plone/Products.CMFPlone

Issue:
Editing in TinyMCE throws errors for missing css-files in Plone 6 classic
See https://6-classic.demo.plone.org/de/frontpage/edit

```
https://6-classic.demo.plone.org/de/++plone++static/plone-compiled.css
https://6-classic.demo.plone.org/de/++plone++static/tinymce-styles.css
https://6-classic.demo.plone.org/de/++plone++static/components/tinymce/skins/lightgray/content.min.css
```

`plone-compiled.css` and `tinymce-styles.css` are added in `Products.CMFPlone.patterns.tinymce.TinyMCESettingsGenerator.get_content_css` and used to be proved by the theme. 
I'm not sure if we need and want any of these.

The third is the value of `content_css` in the TinyMCE Controlpanel. 
In Plone 5.2 that was `++plone++static/components/tinymce-builded/js/tinymce/skins/lightgray/content.min.css` but neither is availabe (or seems to be needed) in Plone 6.



Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/interfaces/controlpanel.py b/Products/CMFPlone/interfaces/controlpanel.py
--- a/Products/CMFPlone/interfaces/controlpanel.py
+++ b/Products/CMFPlone/interfaces/controlpanel.py
@@ -382,18 +382,15 @@ class ITinyMCELayoutSchema(Interface):
     content_css = schema.List(
         title=_("Choose the CSS used in WYSIWYG Editor Area"),
         description=_(
-            "This option enables you to specify a custom CSS file "
-            "that provides content CSS. "
-            "This CSS file is the one used within the editor "
-            "(the editable area). In addition to what is listed, "
-            "here the plone bundle CSS and diazo themes using the "
-            "tinymce-content-css setting are also added."
+            "This option enables you to specify CSS files "
+            "that will be used within the the editable area of the editor "
+            "(e.g. ++plone++mystyles/tinymce.css). "
+            "In addition to what is listed here, "
+            "the barceloneta bundle CSS is also added."
         ),
         value_type=schema.TextLine(),
         missing_value=[],
-        default=[
-            "++plone++static/components/tinymce/" "skins/lightgray/content.min.css"
-        ],
+        default=[],
         required=False,
     )
 
diff --git a/Products/CMFPlone/patterns/tinymce.py b/Products/CMFPlone/patterns/tinymce.py
--- a/Products/CMFPlone/patterns/tinymce.py
+++ b/Products/CMFPlone/patterns/tinymce.py
@@ -32,7 +32,7 @@ def get_theme(self):
         return theming_policy().get_theme()
 
     def get_content_css(self, style_css=""):
-        files = [f"{self.nav_root_url}/++plone++static/plone-compiled.css"]
+        files = []
         if style_css:
             files.extend(style_css.split(","))
         content_css = self.settings.content_css or []
@@ -94,9 +94,7 @@ def get_all_style_formats(self):
 
     def get_tiny_config(self):
         settings = self.settings
-        importcss_file_filter = "%s/++plone++static/tinymce-styles.css" % (
-            self.nav_root_url
-        )
+        importcss_file_filter = ""
 
         theme = self.get_theme()
         if theme and getattr(theme, "tinymce_styles_css", None):


Test patch:
Repository: plone/Products.CMFPlone

Issue:
Allow TinyMCE to be used in inline-mode
Inline-mode of TinyMCE (https://www.tiny.cloud/docs/demo/inline) is nice among other reasons because the edited text looks exactly the way as the saved result. 

To enable it you could simply set `{"inline": "true"}` as the value in the field "Other settings" of the TinyMCE controlpanel. That is enough to trigger it. 

But that fails with `Could not initialize inline editor on invalid inline target element` since the html-tag that renders the TinyMCE is a `<textarea>`. See https://www.tiny.cloud/blog/tinymce-inline-option-not-working for details about that constraint.

The `<textarea>` thing is defined in `plone.app.z3cform.widget.RichTextWidget` which has `TextareaWidget` as `_base`. In `render_input_mode` of the widget it is possible to conditionally render a different html element like `div` around the text. But then fallback to textarea no longer works and saving also fails and and and... 

So it seems that using inline-mode in not straightforward. The question is do we like that option enough to do the required work?



Discussion:
For reference, in Plone 5 you can activate inline editing like so:

```
from plone.app.textfield import RichText
from plone.app.z3cform.widget import RichTextWidget
from plone.autoform.directives import widget

[...]

    # inline: True necessary for reordering rows, otherwise tinymce would not render correctly.
    # tiny config to reduce UI
    widget("description", RichTextWidget, pattern_options={
        "inline": True,
        "tiny": {
            "toolbar": "bold italic bullist unlink plonelink",
            "plugins": ["plonelink", "lists", ],
            "menubar": "",
        },
    })
    # RichText for TinyMCE
    # allowed_mime_types to not get the mimetype selector and for tinymce to actually work.
    # the mimetypeselector has a config for the textfield, but here we are cloning textfields and the mimetypeselector config isn't updated.
    description = RichText(title=u"Beschreibung", required=False, allowed_mime_types=["text/html"])

```

Resolving patch:
diff --git a/Products/CMFPlone/patterns/settings.py b/Products/CMFPlone/patterns/settings.py
--- a/Products/CMFPlone/patterns/settings.py
+++ b/Products/CMFPlone/patterns/settings.py
@@ -137,6 +137,7 @@ def tinymce(self):
             "relatedItems": related_items_config,
             "prependToScalePart": "/@@images/image/",
             "prependToUrl": "{}/resolveuid/".format(site_path.rstrip("/")),
+            "inline": settings.inline,
             "tiny": generator.get_tiny_config(),
             "upload": {
                 "baseUrl": portal_url,


Test patch:
Repository: plone/Products.CMFPlone

Issue:
Case insensitive sort of addon controlpanel items
In the addon controlpanel we are presenting the list of addons without sorting it.

Volto sorts them [case-insensitively by title](https://github.com/plone/volto/blob/master/src/reducers/addons/addons.js#L28) which makes sense. 

We should do the same here in CMFPlone.


Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/controlpanel/browser/quickinstaller.py b/Products/CMFPlone/controlpanel/browser/quickinstaller.py
--- a/Products/CMFPlone/controlpanel/browser/quickinstaller.py
+++ b/Products/CMFPlone/controlpanel/browser/quickinstaller.py
@@ -7,6 +7,7 @@
 from Products.statusmessages.interfaces import IStatusMessage
 from plone.memoize import view
 from zope.component import getAllUtilitiesRegisteredFor
+from zope.i18n import translate
 import logging
 import pkg_resources
 import transaction
@@ -487,20 +488,24 @@ def get_addons(self, apply_filter=None, product_name=None):
 
         return filtered
 
+    def get_sorted_addon_values(self, apply_filter=None, product_name=None):
+        values = self.get_addons(apply_filter, product_name).values()
+        return sorted(values, key=lambda x: translate(x.get('title', ''), context=self.request).upper())
+
     def get_upgrades(self):
         """
         Return a list of products that have upgrades on tap
         """
-        return self.get_addons(apply_filter='upgrades').values()
+        return self.get_sorted_addon_values(apply_filter='upgrades')
 
     def get_installed(self):
-        return self.get_addons(apply_filter='installed').values()
+        return self.get_sorted_addon_values(apply_filter='installed')
 
     def get_available(self):
-        return self.get_addons(apply_filter='available').values()
+        return self.get_sorted_addon_values(apply_filter='available')
 
     def get_broken(self):
-        return self.get_addons(apply_filter='broken').values()
+        return self.get_sorted_addon_values(apply_filter='broken')
 
 
 class UpgradeProductsView(InstallerView):


Test patch:
Repository: plone/Products.CMFPlone

Issue:
Allow to migrate to Volto after updating a site to Plone 6
When Plone is updated to 6 the upgrade-view (@@plone-upgrade) should display a link to the migration to Volto.
See https://github.com/plone/plone.volto/issues/55 for the migration itself.


Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/browser/admin.py b/Products/CMFPlone/browser/admin.py
--- a/Products/CMFPlone/browser/admin.py
+++ b/Products/CMFPlone/browser/admin.py
@@ -343,3 +343,16 @@ def __call__(self):
             )
 
         return self.index()
+
+    def can_migrate_to_volto(self):
+        if not HAS_VOLTO:
+            return False
+        pm = getattr(self.context, 'portal_migration')
+        if pm.getInstanceVersion() < "6005":
+            return False
+        try:
+            from plone.volto.browser import migrate_to_volto
+        except ImportError:
+            return False
+        installer = get_installer(self.context, self.request)
+        return not installer.is_product_installed("plone.volto")


Test patch:
Repository: plone/Products.CMFPlone

Issue:
Missing resource breaks rendering viewlet.resourceregistries.js
if there's a typo or a missing JS resource defined in the resource registries, the `viewlet.resourceregistries.js` gives a traceback and all JS resources are missing.


Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/resources/utils.py b/Products/CMFPlone/resources/utils.py
--- a/Products/CMFPlone/resources/utils.py
+++ b/Products/CMFPlone/resources/utils.py
@@ -52,7 +52,7 @@ def get_resource(context, path):
         return
     try:
         resource = context.unrestrictedTraverse(path)
-    except (NotFound, AttributeError):
+    except (NotFound, AttributeError, KeyError):
         logger.warning(
             f"Could not find resource {path}. You may have to create it first."
         )  # noqa


Test patch:
Repository: plone/Products.CMFPlone

Issue:
Site title entered in the @@plone-addsite form is not set as site title
Plone site title is set in the @@site-controlpanel form and saved in the registry. But the @@plone-addsite form gets the site title from the user and saves it as a Zope property in the portal object.


Related to https://github.com/plone/plone.app.layout/issues/317


Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/factory.py b/Products/CMFPlone/factory.py
--- a/Products/CMFPlone/factory.py
+++ b/Products/CMFPlone/factory.py
@@ -149,6 +149,7 @@ def addPloneSite(context, site_id, title='Plone site', description='',
         reg['plone.available_timezones'] = [portal_timezone]
         reg['plone.default_language'] = default_language
         reg['plone.available_languages'] = [default_language]
+        reg['plone.site_title'] = title
 
         # Install default content types profile if user do not select "example content"
         # during site creation.


Test patch:
diff --git a/Products/CMFPlone/tests/test_factory.py b/Products/CMFPlone/tests/test_factory.py
--- a/Products/CMFPlone/tests/test_factory.py
+++ b/Products/CMFPlone/tests/test_factory.py
@@ -3,6 +3,8 @@
 from Products.CMFPlone.utils import get_installer
 from Products.CMFPlone.testing import PRODUCTS_CMFPLONE_INTEGRATION_TESTING
 from zope.component import queryUtility
+from zope.component import getUtility
+from plone.registry.interfaces import IRegistry
 
 import unittest
 
@@ -53,3 +55,10 @@ def test_site_creation_without_content_but_with_content_types(self):
         # Folder
         fti = queryUtility(IDexterityFTI, name='Folder')
         self.assertIsNotNone(fti)
+
+    def test_site_creation_title_is_set_in_registry(self):
+        """ Plone site title should be stored in registry """
+        ploneSite = addPloneSite(
+            self.app, 'ploneFoo', title='Foo', setup_content=False)
+        registry = getUtility(IRegistry, context=ploneSite)
+        self.assertEqual(registry['plone.site_title'], 'Foo')
Repository: plone/Products.CMFPlone

Issue:
Site title entered in the @@plone-addsite form is not set as site title
Plone site title is set in the @@site-controlpanel form and saved in the registry. But the @@plone-addsite form gets the site title from the user and saves it as a Zope property in the portal object.


Related to https://github.com/plone/plone.app.layout/issues/317


Discussion:

Resolving patch:
diff --git a/Products/CMFPlone/factory.py b/Products/CMFPlone/factory.py
--- a/Products/CMFPlone/factory.py
+++ b/Products/CMFPlone/factory.py
@@ -5,6 +5,7 @@
 from Products.CMFPlone.events import SiteManagerCreatedEvent
 from Products.CMFPlone.interfaces import INonInstallable
 from Products.CMFPlone.Portal import PloneSite
+from Products.CMFPlone.utils import safe_unicode
 from Products.GenericSetup.tool import SetupTool
 from Products.statusmessages.interfaces import IStatusMessage
 from zope.component import queryUtility
@@ -160,6 +161,7 @@ def addPloneSite(context, site_id, title='Plone site', description='',
     reg['plone.available_timezones'] = [portal_timezone]
     reg['plone.default_language'] = default_language
     reg['plone.available_languages'] = [default_language]
+    reg['plone.site_title'] = safe_unicode(title)
 
     # Install default content types profile if user do not select "example content"
     # during site creation.


Test patch:
diff --git a/Products/CMFPlone/tests/test_factory.py b/Products/CMFPlone/tests/test_factory.py
--- a/Products/CMFPlone/tests/test_factory.py
+++ b/Products/CMFPlone/tests/test_factory.py
@@ -4,6 +4,8 @@
 from Products.CMFPlone.utils import get_installer
 from Products.CMFPlone.testing import PRODUCTS_CMFPLONE_INTEGRATION_TESTING
 from zope.component import queryUtility
+from zope.component import getUtility
+from plone.registry.interfaces import IRegistry
 
 import unittest
 
@@ -54,3 +56,10 @@ def test_site_creation_without_content_but_with_content_types(self):
         # Folder
         fti = queryUtility(IDexterityFTI, name='Folder')
         self.assertIsNotNone(fti)
+
+    def test_site_creation_title_is_set_in_registry(self):
+        """ Plone site title should be stored in registry """
+        ploneSite = addPloneSite(
+            self.app, 'ploneFoo', title='Foo', setup_content=False)
+        registry = getUtility(IRegistry, context=ploneSite)
+        self.assertEqual(registry['plone.site_title'], 'Foo')