Closed (won't fix)
Project:
Drupal core
Version:
7.x-dev
Component:
base system
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
9 Feb 2009 at 00:05 UTC
Updated:
23 Aug 2009 at 22:26 UTC
Jump to comment: Most recent file
Comments
Comment #1
catchComment #2
alexanderpas commentedSpot the difference:
- http://api.drupal.org/api/function/element_sort/7 uses ['#weight']
- http://api.drupal.org/api/function/_field_sort_items_helper/7 uses ['_weight']
- http://api.drupal.org/api/function/_field_sort_items_value_helper/7 uses ['_weight']['#value']
- http://api.drupal.org/api/function/drupal_sort_weight/7 uses ['weight']
in my opinion ['weight'] is always wrong, so drupal_sort_weight should be dropped (and all references corrected)
also i think ['_weight']['#value'] is overkill... so we should go for ['_weight'] (or maybe even ['#weight']) but i'm not familiar with the Field API
Comment #3
robloachThe problem is that all of these function differently and all rely on how uasort, or the other PHP sorting methods work.
We used 'weight' instead of '#weight' in drupal_add_js because it didn't really make much sense to have every property without the # prefix, and then weight with it (#315798: JavaScript Patch #2: Weight).
If we were using PHP 5.3, it would be really easy with closures, but this is not the case. In my opinion, it would make more sense to drop element_sort, _field_sort_items_helper and _field_sort_items_value_helper and somehow turn drupal_sort_weight into a generic sorting mechanism.
element_sortdoesn't have to be tailored to sorting form elements (maybe rename todrupal_sort_array, or something?).Comment #4
dave reidHashed this out and I think I've found a solution. I tested this out myself and it seems to work on all the test cases we need:
Therefore, the function can be called in a number of ways, all fitting the current use cases:
Does this seem like an acceptable solution? I can start working on replacing all four functions tomorrow morning.
Comment #5
chx commentedthis does not work. php functions are global and do not have a scope like you used.
Comment #6
robloachBased off of Dave solution ins #4:
........... Hate me.
Comment #7
dave reid@chx I have no idea why then it works for me.
So on further inspection I get the following errors, but the sort magically works somehow. The code with results is in http://drupalbin.com/7978
* Notice: Undefined variable: keys in _drupal_array_sort() (line 25 of /home/davereid/Projects/drupal-head/test.php).
* Warning: Invalid argument supplied for foreach() in _drupal_array_sort() (line 25 of /home/davereid/Projects/drupal-head/test.php).
EDIT: Ok so I've figured out why my function was giving the expected results. RobLoach's improvement actually works properly instead of mistakenly. :)
Comment #8
dave reidInitial patch replacing all the four sort functions with a generic drupal_sort_array().
TODO:
- Benchmarking and profiling
- Check other calls to usort, uasort, etc to see if this method can be expanded to help replace more duplicated code.
Comment #10
robloachHere it is with some tests. Also added the default of '#weight'. There has to be a better way of doing it. Well, at least we have the tests for it, as well as the the API. create_function seems like a huge hack though......
Comment #11
dave reidHmm...since this is such a generic sort function, I'm not sure I agree that we should have a default value for the sort key. I don't know of any other way to get around the create_function. Setting as CNR so I can see how it does with the testing bot.
Comment #13
robloachThe array sorting tests passed..........
Comment #14
catchIs the reference somehow getting messed up? uasort takes by reference, drupal_sort_array() doesn't?
Comment #15
robloachcatch: Hmmmm?
function drupal_sort_array(&$array);Comment #16
catchRob Loach, yes I'm an idiot.
Comment #17
alexanderpas commentedI think this will be much better...
sorry, don't have time for a patch ;)
Comment #18
dave reid@alexanderpas If you intend to pass that function to uasort, it won't work because you can't pass additional parameters via uasort.
Comment #19
alexanderpas commentedfuntions with callback arguments always get me...
Comment #20
catchI don't believe that the field form tests are broken by this.
Comment #22
chx commentedSaving a few lines of code, does it worth to use create_function? I doubt. Can't we instead inspect the data structures being sorted and unify them? At least some of them?
Comment #23
dave reidDid some debugging and figured out what was causing the tests to file. Since the array items were references in theme_field_multiple_value_form():
The following condition in drupal_sort_array() was causing array elements to be set to '0':
which can be fixed by making a local copy of the element:
I also adjusted and improved the tests so it can catch this condition. Also bumping down from critical, since this isn't exactly...critical.
Comment #24
dave reidNot sure how far we could get with trying to standardize our data structures. It will required drupal_add_js (and consequently drupal_add_css) to use a FAPI style array. If not, we'll still have two different sort functions. Plus I have no idea about the field API structures, but on initial review, it's not going to be possible to not have more than two other sort functions.
I'd love someone to show me wrong, but I think this utility function has shown it can be useful throughout core.
Comment #25
dave reidSome initial benchmarking on #23 w ith
ab -c 1 -n 500 http://mysql.drupalhead.local/. FYI, an internal counter in drupal_sort_array() shows that the function is hit 23 times for each request with the patch.Unpatched w/ four different sort functions:
Patched w/ drupal_array_sort:
Comment #26
robloachForgive me if I'm missing something here, but why is the
drupal_sort_array()faster by 0.02 ms? Shouldn't it be slower?Comment #27
dave reidI'll do some more tests, but yeah, it's a little suprising.
I'd also like to take a look at if and how the following functions could be replaced by a general drupal_sort_array(). These are all functions called with usort() or uasort(). The functions I have starred are probably the most likely candidates for replacement.
_system_sort_requirements
_block_compare
_user_sort*
system_sort_modules_by_info_name*
_fitler_list_cmp*
_update_project_status_sort
Comment #28
chx commentedThat's quite likely to be within error margin. It's very likely that within a page request that function plays so little role that it's not measurable really. This does not mean that we want create_function in core, really.
Comment #30
robloachRecreated from HEAD.
Comment #31
chx commentedGenerated functions are so ugly.
try that on.
Comment #33
dave reidErrant GD-related testbot failure...resetting status.
Comment #34
dries commentedI'm not sure I understand the purpose of this patch. To me, this patch adds a layer of complexity and abstraction that wasn't there before. It is much easier to understand uasort() than it is to understand the new sort function.
Comment #35
quicksketchSubscribing. I'm about to make yet another sort function for #445736: Poll does not respect weight in Preview or More button. :P
This patch should take into account adding microweights to prevent elements with the same weight from being reordered (say sorting an array with all the weights = 0).
Comment #36
dries commentedI think this patch is trying to abstract something which is easy enough. Adding a layer of abstraction actually obfuscates things in this case.
Comment #37
joshmillerCleaning up DrupalWTF list... Since this is a won't fix, removing tag...