-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Utilize PropertyAccess component for sorting arrays #159
Utilize PropertyAccess component for sorting arrays #159
Conversation
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.
Aside from my little comments, good job 👍
{ | ||
if (is_array($event->target) && count($event->target) > 1) |
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.
Refactoring and enhancing in the same PR makes the diff roughly hard to read. Please next time create two separate PRs, it will make our life's easier.
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 do you mean? Like first PR purely to refactor and second PR with actual feature pointed into first branch/PR? Sure can do so if you prefer that, even though I prefer having it in all in single PR to prevent conflicts (if there are some requested changes in first PR, it's likely second PR will have to be changed as well). In this case reading the full source is easier than diff though https://github.com/ostrolucky/knp-components/blob/db2daf3016612890b7a296dd5d44ae2bfe88856c/src/Knp/Component/Pager/Event/Subscriber/Sortable/ArraySubscriber.php
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.
Yep that's it. From my point of view it's better to not restructure the code and in the mean time change the contact(s). But don't worry, I'm not asking you to recreate two separate PRs :)
$fieldValue2 = strtolower($object2->{$this->currentSortingFieldGetter}()); | ||
if ($fieldValue1 == $fieldValue2) { | ||
return 0; | ||
if (!is_array($event->target) || !isset($_GET[$event->options['sortFieldParameterName']])) { |
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.
We don't need to sort if there're no items in target.
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.
Usort doesn't call the callback if array is empty. But my style is to purposely leave out such things from top of the function if rest of the body is cheap to execute, because if user misconfigured something else, he will not know about it until he passes non-empty array here E.g. if he enables sorting by a field which is missing from (enabled) whitelist, this subscriber will appear to be working correctly until some data appear there.
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.
Seems reasonable 👍
} | ||
|
||
$this->sortDirection = isset($_GET[$event->options['sortDirectionParameterName']]) && strtolower($_GET[$event->options['sortDirectionParameterName']]) === 'asc' ? 'asc' : 'desc'; | ||
$this->currentSortingField = $_GET[$event->options['sortFieldParameterName']]; |
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 happens if this is empty?
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.
Do you mean empty string, or when that property is actually missing in $_GET? If first, PropertyAccessor will throw error. Second case is handled by isset in top of the method.
edit: i've replaced isset with empty to handle empty value
I've squashed the commits (mainly to fix CI status) |
} | ||
|
||
if (isset($_GET[$event->options['sortDirectionParameterName']])) { | ||
$this->sortDirection = strtolower($_GET[$event->options['sortDirectionParameterName']]); |
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.
I think the ternary was useful, I would prefer to keep it so we're sure either asc
or desc
are used. Also, there's no default value anymore.
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.
I've changed it because end result is same. Sort function works with "asc" only, anything else (even null) is sorted as if it was "desc". But since you prefer to cast it to "desc" before, I'll change it back.
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.
That's true but only when sortFunction
isn't provided, that's why I requested this change at first. But I'm realizing that, sortDirection
and currentSortingField
are not passed to sortFunction
as arguments. I think it would be better to have them, so we don't need to retrieve them again when we implement a custom sort function.
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.
Do you have an idea how to do that though? Usort passes to callback only those two arguments.
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.
Yep, I've got one: create a private proxy method in the subscriber and pass both usort arguments and ours to the custom sort function.
@ostrolucky It's ready to be merged, right? |
@NiR- indeed it is! I don't know about your BC policies though. This will require to slightly change user code for sorting arrays. Before, code required to specify sorting field prefixed with a dot, e.g. |
We try to follow semver at KnpLabs, thus AFAIK this repo too. Rather than introducing a BC change, could you automatically remove heading dot when detected please? |
String comparison when sorting is now utf8 case insensitive Whitelist feature has been enabled for ArraySubscriber Allows to define custom sorting function Default sorting function works also with objects
bc break no longer present, ready to merge! |
Thank you! |
The only data structure currenty ArraySubscriber is able to sort is
object[]
, where object MUST have publicget{sortPropertyName}
method. This PR utilizes symfony propertyaccess component instead, which allows to sort pure array, nested structure, objects with issers, __call methods, objects without any getter but with pulic properties, etc.Besides this main feature of this PR I changed some things, like I uncommented whitelist, turned strtolower into mb_strtolower for utf support, introduced ability to change built in sorting function with custom one and allowed to sort by other data types than strings, such as dates