-
Notifications
You must be signed in to change notification settings - Fork 13
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
[#4] Natural sorting before limiting. #41
Conversation
Thanks for the pull request. I have requested a review by @JeroenDeDauw |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot! There are a number of small issues, and tests for the new behavior are missing. If you could address those, that'd be extra awesome. If not, I'll try to poke at them soonish.
src/Lister/SimpleSubPageFinder.php
Outdated
@@ -201,6 +219,11 @@ private function getOptions() { | |||
|
|||
$options['LIMIT'] = (int)$this->options[self::OPT_LIMIT]; | |||
|
|||
$sort_oder = $this->options[self::OPT_SORT_ORDER]; | |||
if ($sort_oder != self::NONE) { | |||
$options['ORDER BY'] = "LENGTH(page_title) $sort_oder, page_title $sort_oder"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is LENGTH(page_title) $sort_oder
for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there no way to escape these values? My knowledge of the MW DB stuff is a bit rusty... Having no explicit escaping here makes me uneasy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is naive "native sort". It is not so polished as PHP's strnatcmp
but works fine in the most cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does that have to do with sorting by the length of the page title? That is what this SQL does in my understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there no way to escape these values? My knowledge of the MW DB stuff is a bit rusty... Having no explicit escaping here makes me uneasy.
'desc' or 'asc' is not a value, so escape is not applicable.
Only way to set this attribute- is setter setSortOrder
which reject any values except asc
or desc
,
src/Lister/SimpleSubPageFinder.php
Outdated
@@ -45,6 +49,7 @@ public function __construct( DBConnectionProvider $connectionProvider ) { | |||
self::OPT_INCLUDE_REDIRECTS => false, | |||
self::OPT_LIMIT => 500, | |||
self::OPT_OFFSET => 0, | |||
self::OPT_SORT_ORDER => 'asc', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong indent
src/Lister/SimpleSubPageFinder.php
Outdated
*/ | ||
public function setSortOrder( $sortOrder ) { | ||
if ( $sortOrder != self::DESCENDING && $sortOrder != self::ASCENDING && $sortOrder != self::NONE ) { | ||
throw new InvalidArgumentException( 'Invalid $sortOrder specified' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indent
src/Lister/SimpleSubPageFinder.php
Outdated
const OPT_SORT_ORDER = 'sort'; | ||
const ASCENDING = 'asc'; | ||
const DESCENDING = 'desc'; | ||
const NONE = ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SORT_ASCENDING
$this->subPageFinder->setLimit( $limit ); | ||
$this->subPageFinder->setSortOrder( $sortOrder ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This relies on the constant values matching the user input, which is bad practice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inside setSortOrder
I check that $sortOrder is 'asc' or 'desc'. I think this is secure enough.
What alternative should I use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's cool you put in that check - it will make errors more apparent.
The issue here is that there is no abstraction between presentation layer, application logic and data access layer. If that is not clear to you, nvm, I'll take care of it then.
@@ -73,6 +73,7 @@ private function getRenderedList( SubPageList $subPageList, $titleText ) { | |||
'showpage' => new ProcessedParam( 'showpage', true, false ), | |||
'default' => new ProcessedParam( 'default', '', true ), | |||
'limit' => new ProcessedParam( 'limit', 200, true ), | |||
'sort' => new ProcessedParam( 'sort', 'asc', true ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not entirely sure why this was added. I don't see why the test would fail without it just by looking at this PR, but then perhaps I'm being blind.
What is definitely the case is that the new behavior is not tested
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It caused to error "Undefined index: sort"
I think this is because of mocks.
I'm not so good at PHPUnit.
I found a problem with my solution. For example we have subpages:
and then sort it in PHP:
This illustrates problem: sorting and limiting must be or in SQL or in PHP, but not be spread. It's hard to implement real native sorting in SQL so
What do you think, which point I should implement? |
I had a look at the code and found that the situation is not really as simple as I thought. It's not the case that we select some pages from the db and then just sort them. What happens is that they get selected from the db, then manipulated into a tree like data structure which is traversed in TreeListRenderer and has each level individually sorted. From a code architecture level this is kinda weird: why would sorting happen in TreeListRenderer, which is definitely UI code, and not application logic code. I'd be fine with selecting ALL subpages, if that was just the direct ones. However with indirect ones selected as well, I can imagine having a 100 subages that each have 100 themselves, and then you have a problem. So it seems that doing the sorting in SQL is the only approach that is going to work. I'm fine with removing the PHP sorting if SQL is used instead. |
src/Lister/SimpleSubPageFinder.php
Outdated
* | ||
* @throws InvalidArgumentException | ||
*/ | ||
public function setSortOrder( $sortOrder ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent is still messed up. This project uses tabs, you seem to be using spaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, my Idea IDE was not configured properly. Sorry.
No description provided.