Problem/Motivation

Many efforts have been made to make Drupal 8 a great multilingual system. However, content types are never properly sorted when translations contain accentuated characters.

Content types are sorted using asort. Maybe we could set the locale beforehand.

Steps to reproduce

Install Drupal 8
Enable the following modules

  • Configuration Translation
  • Content Translation
  • Interface Translation
  • Language

Add a language (French in the example)
Add a two content types (Show and Zone)
Translate the Show content type to Émission
Switch languages (fr/admin/structure/types)

Expected behavior

To have a list in this order

  • Article
  • Basic page
  • Émission
  • Zone

What happened instead

List was in this order:

  • Article
  • Basic page
  • Zone
  • Émission

Proposed resolution

Use PHP Collator class to sort the items with a fallback to strnatcasecmp() function when PHP intl extension is not installed

Remaining tasks

User interface changes

API changes

NaturalSort::strnatcasecmp function is added

Data model changes

Release notes snippet

CommentFileSizeAuthor
#167 2265487-nr-bot_624jzxa9.txt91 bytesneeds-review-queue-bot
#166 current-es.png4.94 KBnicxvan
#166 current-en.png5.7 KBnicxvan
#166 main-es.png5.24 KBnicxvan
#166 main-en.png6.7 KBnicxvan
#161 2265487-nr-bot_v4uqixsg.txt91 bytesneeds-review-queue-bot
#148 2265487-nr-bot_0o2q9sp2.txt91 bytesneeds-review-queue-bot
#143 2265487-nr-bot_l3mn5s6f.txt98 bytesneeds-review-queue-bot
#135 2265487-nr-bot_y89fpoka.txt91 bytesneeds-review-queue-bot
#133 2265487-nr-bot_kndzbin3.txt91 bytesneeds-review-queue-bot
#130 2265487-nr-bot_16heo7gp.txt98 bytesneeds-review-queue-bot
#127 2265487-nr-bot_2u_yw1gi.txt91 bytesneeds-review-queue-bot
#124 2265487-nr-bot_hq46t8a7.txt91 bytesneeds-review-queue-bot
#122 2265487-nr-bot_sxgfja1t.txt91 bytesneeds-review-queue-bot
#120 2265487-nr-bot_jz0ivgjc.txt91 bytesneeds-review-queue-bot
#116 2265487-nr-bot_5cn822yh.txt91 bytesneeds-review-queue-bot
#114 2265487-nr-bot_p9yv_tqc.txt98 bytesneeds-review-queue-bot
#112 2265487-nr-bot_d9ntbzx4.txt91 bytesneeds-review-queue-bot
#109 2265487-nr-bot_rf012mfl.txt91 bytesneeds-review-queue-bot
#62 2265487-nr-bot.txt90 bytesneeds-review-queue-bot
#58 2265487-nr-bot.txt90 bytesneeds-review-queue-bot
#55 2265487-nr-bot.txt90 bytesneeds-review-queue-bot
#51 2265487-nr-bot.txt90 bytesneeds-review-queue-bot
#38 2265487-38.patch9.03 KBsleitner
#36 reroll_diff_34-36.txt3.18 KBtanuj.
#36 2265487-36.patch9.03 KBtanuj.
#35 2265487-nr-bot.txt85 bytesneeds-review-queue-bot
#34 interdiff33-34.patch730 bytessleitner
#34 2265487-34.patch9.12 KBsleitner
#33 interdiff24-33.txt9.46 KBsleitner
#33 2265487-33.patch9.08 KBsleitner
#27 aftr_vocab.png667.46 KBsonam.chaturvedi
#27 aftr_shortcut.png628.72 KBsonam.chaturvedi
#27 aftr_media.png781.07 KBsonam.chaturvedi
#27 aftr_contactform.png697.47 KBsonam.chaturvedi
#27 aftr_comment_type.png770.91 KBsonam.chaturvedi
#27 aftr_content_type.png871.73 KBsonam.chaturvedi
#27 bef_comment_types.png245.48 KBsonam.chaturvedi
#27 bef_content_type.png679.23 KBsonam.chaturvedi
#24 2265487-24.patch4.67 KBsleitner
#23 2265487-23.patch3.2 KBsleitner
#21 2265487-21.patch2.53 KBsleitner
#19 2265487-19.patch2.38 KBsleitner
#17 2265487-17.patch2.38 KBsleitner
#18 2265487-18.patch2.41 KBsleitner

Issue fork drupal-2265487

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

nlambert’s picture

Category: Feature request » Bug report

Labelling as a bug

nlambert’s picture

Issue summary: View changes

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
catch’s picture

Title: Localized sorting » When content types are sorted, locale isn't taken into account
Issue tags: +Bug Smash Initiative, +Needs tests

This could use a test case to start with.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

sleitner’s picture

I think there are a lot more lists not sorted correctly when translated. In core strnatcasecmp, usort, uasort, natcasesort is used a lot.

sleitner’s picture

StatusFileSize
new2.38 KB

Sorts all ConfigEntityBundleBase based lists with transliteration

sleitner’s picture

StatusFileSize
new2.41 KB
sleitner’s picture

StatusFileSize
new2.38 KB
sleitner’s picture

Status: Active » Needs review

Sorts all ConfigEntityBundleBase based lists with transliteration:

  • BlockContentType
  • CommentType
  • ContactForm
  • MediaType
  • NodeType
  • ShortcutSet
  • Vocabulary
sleitner’s picture

Status: Needs review » Active
StatusFileSize
new2.53 KB

Sorts all ConfigEntityBase based lists with transliteration

sleitner’s picture

Status: Active » Needs work
sleitner’s picture

StatusFileSize
new3.2 KB
sleitner’s picture

StatusFileSize
new4.67 KB
sleitner’s picture

Status: Needs work » Needs review

Sorts all ConfigEntityBase based lists with weight or transliterated label with test in ConfigEntityBaseUnitTest:
DateFormat, EntityFormDisplay, EntityViewDisplay, EntityFormMode, EntityViewMode, FieldConfig, Block, Editor, FilterFormat, ImageStyle, ConfigurableLanguage, ContentLanguageSettings, ResponsiveImageStyle, SearchPage, Action, Menu, Tour, Role, View, Workflow, BlockContentType, CommentType, ContactForm, MediaType, NodeType, ShortcutSet, Vocabulary

sleitner’s picture

Title: When content types are sorted, locale isn't taken into account » Lists with items containing non-ascii characters are not sorted correctly
sonam.chaturvedi’s picture

StatusFileSize
new679.23 KB
new245.48 KB
new871.73 KB
new770.91 KB
new697.47 KB
new781.07 KB
new628.72 KB
new667.46 KB

Verified and tested patch #24 on 10.1.x-dev. Patch applied successfully.

Test Steps:
1. Enable the following modules - Configuration Translation, Content Translation, Interface Translation, Language
2. Add a language (French in the example)
3. Add a two content types (Show and Zone)
4. Translate the Show content type to Émission
5. Switch languages (fr/admin/structure/types)
6. Verify content types are ordered alphabetically
7. Verify this for other bundle types - CommentType, ContactForm, MediaType, NodeType, ShortcutSet, Vocabulary, etc.

Test Results: Bundles with non-ascii character are ordered alphabetically.

Before Patch:
bef patch content type

bef patch comment type

After Patch:
after pat24 content type

aftr patch comment type

after patch contact

after patch media

after patch shortcut

after patch vocab

sleitner’s picture

Issue tags: -Needs tests
sleitner’s picture

Title: Lists with items containing non-ascii characters are not sorted correctly » ConfigEntity based lists with items containing non-ascii characters are not sorted correctly
ameymudras’s picture

Status: Needs review » Reviewed & tested by the community

Tested on 10.1.x and following is my observation

1. The issue summary is clear and explains the overall problem
2. Testing steps have been provided and was able to reproduce the issue
3. Patch #24 applies cleanly and the non-ASCII config entity sort correctly
4. Tests have been included and passes for #24
5. Did code review and no issues were identified

Marking this as RTBC, not including additional screenshots. Already provided in #27

longwave’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
@@ -226,14 +226,22 @@ public function createDuplicate() {
+      $language_id = \Drupal::service('language_manager')
...
+      $a_label = \Drupal::service('transliteration')->transliterate(
...
+      $b_label = \Drupal::service('transliteration')->transliterate(

A bit concerned about calling all these services inside the sort callback, because it feels like this is not going to be very performant in a case when there are hundreds of items or more to sort.

We could at least extract the transliteration service to a variable, and also skip transliterating the empty string if it is falsy? Is there a way of injecting at least the language ID, given that it never changes, or the transliteration service itself?

Also, do we have the same concerns about sorting in different languages as was raised in #3262017-90: Country list is not correctly sorted when it's localized with accents (e.g. German, Turkish)? Is transliterating the right thing to do in all cases?

sleitner’s picture

Status: Needs review » Needs work
sleitner’s picture

Status: Needs work » Needs review
StatusFileSize
new9.08 KB
new9.46 KB

@longwave : I remove transliteration and added the Collator like in #3262017: Country list is not correctly sorted when it's localized with accents (e.g. German, Turkish).

sleitner’s picture

StatusFileSize
new9.12 KB
new730 bytes

To prevent MethodArgumentValueNotImplemented exception in Collator, language_id en is used if intl extension is not installed.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new85 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

tanuj.’s picture

Status: Needs work » Needs review
StatusFileSize
new9.03 KB
new3.18 KB

patch #34 doesn't apply to drupal core and throws this error:

error: while searching for:
   * {@inheritdoc}
   */
  protected function setUp(): void {
    $this->query = $this->createMock('Drupal\Core\Entity\Query\QueryInterface');

    $this->storage = $this->createMock('Drupal\Core\Config\Entity\ConfigEntityStorageInterface');

error: patch failed: core/modules/search/tests/src/Unit/SearchPageRepositoryTest.php:50
error: core/modules/search/tests/src/Unit/SearchPageRepositoryTest.php: patch does not apply

adding a new patch with reroll diff

longwave’s picture

The new polyfill and intl extension have the same considerations as #3262017: Country list is not correctly sorted when it's localized with accents (e.g. German, Turkish) so this will need to wait for the decision over there first.

sleitner’s picture

StatusFileSize
new9.03 KB

Reroll

Status: Needs review » Needs work

The last submitted patch, 38: 2265487-38.patch, failed testing. View results

sleitner’s picture

Status: Needs work » Needs review
smustgrave’s picture

smustgrave’s picture

Also posted to the #needs-review-queue-initative slack channel so hopefully a framework manager can take a look at that one.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

sleitner’s picture

Status: Postponed » Needs work

Unpostpone it. #3262017: Country list is not correctly sorted when it's localized with accents (e.g. German, Turkish) is postponed because nobody wants to break the API.

sleitner’s picture

Status: Needs work » Needs review

Converted to MR

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update, +Needs framework manager review

Can the issue summary be updated to use the standard template please.

Hiding all patches for clarity as fix is in MR now.

Will need framework manager review for the package being added.

sleitner’s picture

Issue summary: View changes
sleitner’s picture

Issue summary: View changes
sleitner’s picture

Status: Needs work » Needs review
Issue tags: -Needs issue summary update
needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new90 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work

Took a look at the MR before pinging a framework manager and seems we are updating several packages that seem unrelated to this. Can those be reverted please.

sleitner’s picture

Status: Needs work » Needs review
needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new90 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Needs review

Rerolled again

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

I can't make the call about the new package but the MR does fix the problem described in the issue summary. Moving to RTBC to put in front of the framework managers.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new90 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community

Rerolled again

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Needs framework manager review +Needs issue summary update

It's fine to add a new Symfony polyfill, (more a release management decision than a framework one) but there should really be a dependency evaluation in the issue summary here per https://www.drupal.org/about/core/policies/core-dependency-policies/depe... - can be very short because we know the answers in this case.

sleitner’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs issue summary update

Dependency evaluation added to issue summary

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new90 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Needs review
Issue tags: +no-needs-review-bot
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Remarking as dependency eval has been added to summary.

quietone’s picture

I read the IS, comments and the MR. The only possible thing to consider is @longwave's point in #31 about calling services inside the sort callback "is not going to be very performant in a case when there are hundreds of items or more to sort". The transliteration service was removed from an earlier iteration of the MR but is still is getting the LanguageManager.

Leaving at RTBC.

quietone’s picture

larowlan’s picture

Status: Reviewed & tested by the community » Needs work

#31 still to be addressed.
MR no longer applies in the meantime.

sleitner’s picture

Status: Needs work » Needs review

The service is moved to a new function
public static function sortEntities(array &$entities): bool
which calls a new compare function
public static function compare(ConfigEntityInterface $a, ConfigEntityInterface $b, \Collator $collator): int.

The sort functionpublic static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) is now deprecated in all child classes.

smustgrave’s picture

Status: Needs review » Needs work

appears to have merge conflict but the tag no-needs-review-bot kept the bot from getting it.

sleitner’s picture

Status: Needs work » Needs review

Rerolled

larowlan’s picture

Status: Needs review » Needs work
Issue tags: +11.2.0 release priority

Left a review on the MR
Would it be simpler (less re-rolls etc) to get the new dependency in first in a separate issue?

sleitner’s picture

Status: Needs work » Needs review

@larowlan all references to 11.1 are replaced by 11.2

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Feedback appears to be addressed.

longwave’s picture

Do we need to deprecate sort()? Can we add the Collator as an optional argument to the existing method, and trigger a deprecation if it's not passed in?

longwave’s picture

Status: Reviewed & tested by the community » Needs work

Also there is a merge conflict, some out of scope changes in composer.json/lock.

sleitner’s picture

Status: Needs work » Needs review

@longwave you pointed in #31 about calling services inside the sort callback "is not going to be very performant in a case when there are hundreds of items or more to sort". The solution is to place the service outside the compare function sort().

Furthermore the function name sort() does not reflect its function. It is just comparing the two values, it is not sorting anything.

The merge conflict is resolved.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

@longwave going to go on a limb and say this is good. The lock file seems to only show the new dependency I believe.

sleitner’s picture

Rerolled

sleitner’s picture

Rerolled

catch’s picture

Status: Reviewed & tested by the community » Needs work

Unfortunately this needs another rebase, the MR looks good to me.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community

Rebased. What else needs to be done before the merge?

  • catch committed 0576f60c on 11.x
    Issue #2265487 by sleitner, tanuj., longwave, nlambert, larowlan,...
catch’s picture

Status: Reviewed & tested by the community » Fixed

I don't think there's anything left to do here, RTBC queue has been very busy (hard to keep under 100 issues even with over 100 commits/month and many more reviews).

Committed/pushed to 11.x, thanks!

acbramley’s picture

Status: Fixed » Needs work

This blows up sites that don't have the intl extension

adam@8fa2a3a71304:data $ drush cr
PHP Fatal error:  Uncaught Error: Class "Collator" not found in /data/app/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php:239

I think the intention of this code was to check the extension was loaded before initialising the $collator but I can't quite follow:

$collator = \Collator::create((!extension_loaded('intl')) ? ('en') : (\Drupal::service('language_manager')->getCurrentLanguage()->getId()));
acbramley’s picture

Status: Needs work » Fixed

::compare requires a Collator to be passed to it as well so we'll need to allow that the handle it being NULL?

I'm guessing this passed CI because that environment has the extension installed, but it's not listed as a requirement in core's composer.json...

I missed the symfony polyfill in the MR though which does look like it works

catch’s picture

Priority: Normal » Critical
Status: Fixed » Needs work

Just seen #3516545: Symfony\Polyfill\Intl\Icu\Collator::compare() is not implemented let's revert this and recommit with that fixed.

  • catch committed 4e9d819e on 11.x
    Revert "Issue #2265487 by sleitner, tanuj., longwave, nlambert, larowlan...
catch’s picture

Reverted the commit and marked #3516545: Symfony\Polyfill\Intl\Icu\Collator::compare() is not implemented as duplicate. Let's fix that here and re-commit.

I think we should also open an upstream bug report against Symfony to implement the method, then we wouldn't need the checks added by that MR and could go back to the original code committed here.

catch’s picture

Priority: Critical » Normal

sleitner’s picture

Status: Needs work » Needs review

Fixed the problem in MR11697 and tested it here in tugboat. Please review.

sleitner’s picture

@acbramley : Test manually or automatically? Manually: "View live preview" via Tugboat next to the MR on the top of this issue page. In the tugboat PHP intl extension is not installed, at the moment. Same in Simplytest.me

acbramley’s picture

Test manually or automatically

I meant in automated tests, i.e to catch the bug that caused this to be reverted

penyaskito’s picture

Status: Needs review » Needs work

NW per the test. Also not sure why changing the API is necessary here.

sleitner’s picture

Any idea how to test the fallback to symfony/polyfill-intl-icu ?

larowlan’s picture

sleitner’s picture

The PHP intl extension is compiled into PHP in the docker image. If the PHP intl extension should be optional, the base docker image has to be changed to install intl with pecl.

I compared the composer.json ext-* requirements and the extensions installed in the gitlab docker image. There are many PHP extensions installed that are not listed as required by core and its dependencies. Doesn't this lead to potential post-installation problems on systems that don't have the usual large number of PHP extensions installed (e.g simplytest.me)? If the PHP extensions are only suggested,, they should be disableable for testing.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

sleitner’s picture

Status: Needs work » Needs review

symfony/polyfill-intl-icu:^1,34 now implements Collator::compare

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: -no-needs-review-bot

sorry this one needs a rebase now.

sleitner’s picture

Status: Needs work » Needs review

Rebased, needs review

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Believe this one is ready again. Would least be good to get into 12

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

The solution of adding Symfony's intl polyfill here feels really odd because we don't actually use it - we only use it to create a collator class that is then never used - because if the intl extension is not installed we fallback to strnatcasecmp. Why are we not comparing using Symfony's collator?

alexpott’s picture

Another thing about the current solution is arguably you're going to get better sorting on english sites without intl installed.

$arr = ['Format 10x10', 'Format 20x20', 'Format 100x100'];
print "strnatcasecmp:\n";
usort($arr, 'strnatcasecmp');
var_dump($arr);

print "\n\nstrcasecmp:\n";
usort($arr, 'strcasecmp');
var_dump($arr);

print "\n\nCollator:\n";
$collator = new Collator('en');
// 2. Use usort with the collator's compare method
usort($arr, [$collator, 'compare']);
var_dump($arr);

The output;

strnatcasecmp:
array(3) {
  [0]=>
  string(12) "Format 10x10"
  [1]=>
  string(12) "Format 20x20"
  [2]=>
  string(14) "Format 100x100"
}


strcasecmp:
array(3) {
  [0]=>
  string(14) "Format 100x100"
  [1]=>
  string(12) "Format 10x10"
  [2]=>
  string(12) "Format 20x20"
}


Collator:
array(3) {
  [0]=>
  string(14) "Format 100x100"
  [1]=>
  string(12) "Format 10x10"
  [2]=>
  string(12) "Format 20x20"
}

Link to code: https://3v4l.org/ZbOPJ#v8.4.16

alexpott’s picture

So there's a fix for this - we need to do $collator->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); See https://3v4l.org/rdO0q#v8.4.16

Obviously symfony's collator doesn't support this so I think that's yet another argument for not using it.

alexpott’s picture

Here's what I think we should do.

  1. Remove the symfony polyfill
  2. If the intl extension is isntalled create a collator and set the Numeric Collation attribute.
  3. Allow the usort callback to accept a collator or NULL - if null fallback to strnatcasecmp otherwise use the collator.
sleitner’s picture

Status: Needs work » Needs review
  • Removed the symfony polyfill
  • If the intl extension is installed, a collator is created and set the Numeric Collation attribute.
  • Allow the usort callback to accept a collator or NULL - if null fallback to strnatcasecmp otherwise use the collator.
  • A new deprecation test for Block::sort in BlockRenderOrderTest
needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Needs review
  • Removed meaningless comment
  • Changed unit test with relevant label
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Since I can't close threads I left check marks on them but from what I can tell feedback was addressed

My only comment was the location of the deprecation test but since it'll go away in 13 I'm going to assume none issue

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new98 bytes

The Needs Review Queue Bot tested this issue. The merge request has merge conflicts and cannot be merged. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs issue summary update

I've removed the dependency evaluation as it is no longer relevant but we also need to update the issue summary to reflect what is changing here. Can be set back to RTBC once that is done.

sleitner’s picture

Issue summary: View changes
Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs issue summary update
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community

sleitner changed the visibility of the branch 11.x to hidden.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

acbramley’s picture

Saving @sleitner another rebase/conflict resolution in the baseline. Will chase some committers to see if we can get this in finally.

acbramley’s picture

Status: Needs work » Reviewed & tested by the community
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new98 bytes

The Needs Review Queue Bot tested this issue. The merge request has merge conflicts and cannot be merged. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
smustgrave’s picture

@sleitner you rock for keeping up with all the rebases

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

alexpott’s picture

One thing I keep pondering with this issue is does the string comparison stuff belong in the config system or somewhere more generic - like this is probably an issue when sorting other things using strnatcasecmp... for example:

  • \Drupal\Component\Utility\SortArray::sortByKeyString
  • \Drupal\Core\Plugin\CategorizingPluginManagerTrait::getSortedDefinitions
  • \Drupal\Core\Plugin\DefaultLazyPluginCollection::sortHelper
  • \Drupal\config\Form\ConfigSingleExportForm::buildForm
  • \Drupal\config\Form\ConfigSingleImportForm::buildForm
  • \Drupal\field_ui\Controller\EntityViewDisplayOverviewController::overview (interesting because it is based on config entities and will end up sorting them wrong :) )
  • \Drupal\filter\FilterPluginCollection::sortHelper
  • \Drupal\help\Plugin\HelpSection\HelpTopicSection::getPlugins
  • \Drupal\workspaces\WorkspaceRepository::loadTree

All of these proably should be using a locale aware version of strnatcasecmp() where possible.

sleitner’s picture

@alexpott I think a helper \Drupal\Component\Utility\SortArray would be a good idea to make it more generic.
For example like this:

public static function sortByString(string $a, string $b, ?\Collator $collator): int {
      if (isset($collator)) {
        return $collator->compare($a, $b);
      }
      return strnatcasecmp($a, $b);
}

I think there are more array sorts which use non-optimal compare helpers. But this is a follow-up.

sleitner’s picture

Status: Needs work » Needs review

@alexpott Should the other things using strnatcasecmp be handled in a follow-up?
I added SortArray::sortByString and SortArray::createSortCollator

alexpott’s picture

@sleitner nice work! And yes fixing the other places is all follow-up material.

sleitner’s picture

@alexpott \Drupal::service() is moved back to the entity and documentation is improved

sleitner’s picture

Issue summary: View changes
sleitner’s picture

Issue summary: View changes
needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new98 bytes

The Needs Review Queue Bot tested this issue. The merge request has merge conflicts and cannot be merged. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Needs review
acbramley’s picture

Status: Needs review » Reviewed & tested by the community

I've reviewed all the changes from @alexpott's review and they're looking good. I think this should be good to go now

godotislate changed the visibility of the branch 2265487-configentity-based-lists to hidden.

godotislate changed the visibility of the branch 2265487-configentity-based-lists to active.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Just a few comment nits added to the MR - most with suggestions...

sleitner’s picture

Status: Needs work » Reviewed & tested by the community

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

I've been reviewing this code for quite a while and @sleitner has done an amazing job of keeping up with all my reviews. Thanks for your patience and persistence.

While reviewing the code I've always had two nagging doubts at the back of my mind:

  1. The disruption to existing config entity sorting is hard and real - if a custom or contrib module has a config entity with an override of ::sort and call to ::sort then there are situations where no deprecations is issued. And code that sorts multiple types of config entities will have unexpected results until the whole ecosystem has updated - it won't have a way to call sort or sortEntities depending on what type of config entities it is sorting...
  2. It's not just config entities - all usage of strnatcasecmp() is problematic on a non-english site - how can we minimise disruption but provide a good fix for everywhere.

Soooo.... I'm proposing we go for a different solution. In this issue we add a new utility class that provides a container and language aware alternative to strnatcasecmp() and we convert config entities to use it. And then in a follow-up we introduce a PHPCS rule or PHPStan rule to detect strnatcasecmp() and tell people to use the drop in replacement. See the new MR https://git.drupalcode.org/project/drupal/-/merge_requests/16947

alexpott’s picture

For example, I think the new MR will make solving #3262017: Country list is not correctly sorted when it's localized with accents (e.g. German, Turkish) quite easy - we either swap to the new method supplied here - or we add a natcasesort to the new utility class for even more win.

alexpott’s picture

As the collators are stored in a static class we need to look at the memory usage. A collator takes up 64 bytes and it is highly unlikely the language will be swapping around a lot so I don't think this is an issue.

sleitner’s picture

The new solution sounds good. Will there be performance issues if the languageManager is called every time a comparison is made in large lists? (#31)

I readded the new NaturalSort::strnatcasecmp() to Language and Block .

A new NaturalSort::natcasesort() could call the languageManager outside of the comparison only once.

alexpott’s picture

@sleitner - thanks for fixing up Block - nice catch.

I'm not concerned about performance the current langcode is cached in both language managers provided by core.

sleitner’s picture

Added NaturalSort::natcasesort() with tests

sleitner’s picture

Issue summary: View changes

sleitner changed the visibility of the branch 2265487-configentity-based-lists to hidden.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Needs review

I removed NaturalSort::natcasesort for now

alexpott’s picture

This looks great now. Definitely file a follow-up to add it back and test it and replace natcasesort usage everywhere.

I'm updating / deleting the CRs where appropriate.

sleitner’s picture

Issue summary: View changes
nicxvan’s picture

I'm working through testing this, I'll share my notes in a bit, but for now I created the follow up mentioned in 163.

I added a note to the CR about the natural sort numbers.

nicxvan’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new6.7 KB
new5.24 KB
new5.7 KB
new4.94 KB

Took a bit of effort to test, I was not seeing the expected results, I think there might be something going on separately there so I wouldn't read too much into it.
I did this on a fresh install and it worked both on the english only version and a fresh install that had both english and spanish enabled.

I created several content types one with Émission then when I added the spanish translation I translated it to an ñ.

I've attached 4 screenshots:

Main in English
Main in English
Main in Spanish
Main in Spanish

This branch in English
This branch in English
This branch in Spanish
This branch in Spanish

I really wish we could test this with and without the intl extension in CI, but I think it's fair to leave out here.
This is a great improvement even for just single language sites!

I read through the MR a couple of times and didn't see anything that hadn't already been addressed in the numerous revisions.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

sleitner’s picture

Status: Needs work » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 8cd44d484e3 to main. Thanks!

Given we're in beta freeze for both 11.5.0 and 12.0.0 - I've not backported this. This would be safe to backport as there is no API change here only addition so we might consider doing that once the freeze is over to allow contrib to adopt the fix earlier.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • alexpott committed 8cd44d48 on main
    fix: #2265487 ConfigEntity based lists with items containing non-ascii...
longwave’s picture

Version: main » 12.0.x-dev
Status: Fixed » Patch (to be ported)

Let's consider backporting this while we are in beta for 11.5 and 12.0.