Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed JS sort comparator to be consistent between JS and PHP #7254

Merged
merged 2 commits into from
Sep 16, 2014

Conversation

PVince81
Copy link
Contributor

  • added OC.Util.naturalSortComparator that uses the same algo that was
    used for the user list
  • changed user list and files list to use OC.Util.naturalSortComparator
  • removed toLowerCase() and changed the comparator to use
    String.localeCompare()
  • added unit tests

Fixes for #7059, #3804

@PVince81
Copy link
Contributor Author

Looks like it doesn't work correctly when sorting file names like "a.txt", "a10.txt", "a2.txt"

@PVince81
Copy link
Contributor Author

@PVince81
Copy link
Contributor Author

  • Fix issue with sorting with capitalized umlauts

This is needed to make the sort order exactly the same as in JS.

@PVince81
Copy link
Contributor Author

  • Try and make it consistent across platforms 😦

@PVince81
Copy link
Contributor Author

  • Change the browser locale: run unit tests, check that the sort order after creating files/folders (JS sort) is still the same as after refreshing the page (PHP sort)

@bantu
Copy link

bantu commented Feb 19, 2014

I don't like how a single class is used for everything.

@@ -17,7 +17,7 @@
"globals": {
"console": true,
"it": true,
"itx": true,
"xit": true,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a related change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, 'itx' was a mistake and one of the test uses "xit" (the phantomJS exclusion) which reminded me that this was wrong.

@bantu
Copy link

bantu commented Feb 19, 2014

👎

Please extract the PHP comperator into its own class instead of using the Util class. Have a look at https://github.com/owncloud/core/pull/6778/files for inspiration. Is this maybe even the same or a related comperator?

@bantu
Copy link

bantu commented Feb 19, 2014

You are saying this is performing a "natural sort". There are also the functions natsort() and natcasesort(), so it would be useful to document the differences between your implementation and these in the class description.
http://php.net/natsort

// Needed because PHP doesn't sort correctly when numbers are enclosed in
// parenthesis, even with NUMERIC_COLLATION enabled.
// For example it gave ["test (2).txt", "test.txt"]
// instead of ["test.txt", "test (2).txt"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bantu documented here, that's one of the differences with natsort.
Also natsort didn't sort the umlauts properly.

@PVince81
Copy link
Contributor Author

@bantu I'll extract the comparator into a new class since it's already having three functions which is a bit too much for the Util class.
Would it be ok to keep Util::naturalSortComparator() and make that one use the new class ?

This sort is not the same as the one you linked (already discussed with @blizzz)

@bantu
Copy link

bantu commented Feb 19, 2014

@PVince81 Sounds good.

@PVince81
Copy link
Contributor Author

Rebased+squashed.

I've moved the sorting algo into a separate class "OC_NaturalSort".

Still need to test this branch on IE, Safari and other browsers.

*
*/
class OC_NaturalSort {
private static $collator;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything (methods too) should be non-static here. You should create instances of classes. In general, the number of "good use cases" for static is very limited.

@bantu
Copy link

bantu commented Feb 20, 2014

@PVince81 More work is required here.

From an archetictural standpoint it might be a good idea to have multiple Comparator implementation, and a single Sorter that takes an instance of a Comparator and does the sorting. Not sure whether that is easily possible, though.

@bantu bantu closed this Feb 20, 2014
@bantu bantu reopened this Feb 20, 2014
@PVince81
Copy link
Contributor Author

Opps, the file was supposed to be naturalsort.php, I might have committed it twice.
Will fix.

I wasn't sure whether to use a comparator instance or class, but ok I can change it to be an instance.
Is a static method getInstance() ok ? (PHP pattern-wise)

@bantu
Copy link

bantu commented Feb 20, 2014

I wasn't sure whether to use a comparator instance or class, but ok I can change it to be an instance.
Is a static method getInstance() ok ? (PHP pattern-wise)

Not sure why that would be required. I would suggest to just use the new operator.

@PVince81
Copy link
Contributor Author

@bantu I've just deleted "naturalsortcomparator.php" which was the wrong class, the correct one is "naturalsort.php"

I don't want to "new" the class multiple times in the same php call.
getInstance() would create an instance once and returned the cached one.

@icewind1991 any comments about this pattern ?

@bantu
Copy link

bantu commented Feb 20, 2014

I don't want to "new" the class multiple times in the same php call.
getInstance() would create an instance once and returned the cached one.

Okay. I see. Not sure whether it would be possible to have this in the container where it would be ensured that it is only created once.

if (aNum == aa[x] && bNum == bb[x]) {
return aNum - bNum;
} else {
return aa[x].localeCompare(bb[x], 'en');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the locale be determined from the used language?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally yes, but in our case we want it to match the sorting of PHP which locale is always set to English.
From my test cases it worked quite well even for German umlauts and Chinese characters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment explaining that?

@icewind1991
Copy link
Contributor

I don't want to "new" the class multiple times in the same php call.
getInstance() would create an instance once and returned the cached one.

Okay. I see. Not sure whether it would be possible to have this in the container where it would be ensured that it is only created once.

We have the server container for that (OC::$server)

@scrutinizer-notifier
Copy link

A new inspection was created.

@PVince81
Copy link
Contributor Author

Rebased onto master, should run on Travis now.

@PVince81
Copy link
Contributor Author

@DeepDiver1975 @MorrisJobke segfault on Jenkins.
Shouldn't it run on Travis now ?

@MorrisJobke
Copy link
Contributor

@PVince81 They run in parallel. Travis is just too slow yet. (just 5 jobs at the same time isn't enough to manage our workload)

@ghost
Copy link

ghost commented Aug 19, 2014

🚀 Test Passed. 🚀
Refer to this link for build results: https://ci.owncloud.org/job/pull-request-analyser/6802/

@PVince81
Copy link
Contributor Author

Please review, unit tests finally pass!

@MorrisJobke MorrisJobke modified the milestones: ownCloud 7.0.2, 2014-sprint-02-current Aug 20, 2014
@MorrisJobke
Copy link
Contributor

👎 This doesn't fix the order after the reload.

@MorrisJobke
Copy link
Contributor

Sorry: This fixes #7059 but not the sorting of the umlauts (correct: A Ä Z - this branch and master: A Z Ä) #3804

@PVince81
Copy link
Contributor Author

Hmm strange, it should. Will try again.

@craigpg craigpg modified the milestones: 2014-sprint-03-next, 2014-sprint-02-current Sep 2, 2014
@PVince81
Copy link
Contributor Author

@MorrisJobke works for me.
I created three folders, "A", "Ä" and "Z" in the web UI. They are sorted correctly.
Then I refresh the page, they are still sorted correctly.
They do in Chrome.

Please provide more details and make sure you have the latest version of this branch that was rebased multiple times already.

Thanks.

@MorrisJobke
Copy link
Contributor

I just checked out the latest change, and tried with firefox and chromium: https://cloud.morrisjobke.de/public.php?service=files&t=cac3ab8f16cca86e1e9b6bd4f09b3a3b

Both sort in the wrong way after the refresh. Are any special PHP modules required?

@MorrisJobke
Copy link
Contributor

Are any special PHP modules required?

I just enabled the intl module -.- I will try again dum-di-dum

@MorrisJobke
Copy link
Contributor

Nice one: Works excellent now 👍

@craigpg craigpg modified the milestones: 2014-sprint-04-current, 2014-sprint-03 Sep 15, 2014
@PVince81
Copy link
Contributor Author

@jancborchardt have you had a look at this ?

This needs another reviewer @th3fallen @LukasReschke

@LukasReschke
Copy link
Member

👍

LukasReschke added a commit that referenced this pull request Sep 16, 2014
Fixed JS sort comparator to be consistent between JS and PHP
@LukasReschke LukasReschke merged commit d2743e6 into master Sep 16, 2014
@LukasReschke LukasReschke deleted the core-sortalgo branch September 16, 2014 15:29
@lock lock bot locked as resolved and limited conversation to collaborators Aug 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants