[wp-trac] [WordPress Trac] #19040: get_posts() expects invalid 'orderby' arguments + suggestion
WordPress Trac
wp-trac at lists.automattic.com
Mon Oct 24 20:03:09 UTC 2011
#19040: get_posts() expects invalid 'orderby' arguments + suggestion
--------------------------+-----------------------------
Reporter: abrcam | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Query | Version: 3.2.1
Severity: normal | Keywords:
--------------------------+-----------------------------
The `get_children()` or `get_posts()` template functions which call the
`WP_query::get_posts()` method expect wrong parameters, for example,
`date`. The actual column is called `post_date` but line 2320 of `wp-
includes/query.php` is:
{{{
$allowed_keys = array('author', 'date', 'title',
'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count');
}}}
and further down at line 2329 there is:
{{{
$orderby_array = array();
foreach ( explode( ' ', $q['orderby'] ) as $i =>
$orderby ) {
// Only allow certain values for safety
if ( ! in_array($orderby, $allowed_keys) )
continue;
}}}
The same goes for `author`, `title`, `modified`, etc. Some of them are
correct though: `ID`, `menu_order`, `comment_count`.
If `get_posts()` is called without specifying any `orderby` argument, then
it works fine since the default is correct in line 2314:
{{{
if ( empty($q['orderby']) ) {
$orderby = "$wpdb->posts.post_date " .
$q['order'];
}}}
but if the `orderby` argument is specified and if it includes `post_date`
or other correct column names, then they are ignored, e.g.:
{{{
$images = get_children(array(
'post_type' => 'attachment',
'post_mime_type' => 'image',
'post_parent' => get_the_ID(),
'orderby' => 'menu_order post_date',
'order' => 'ASC',
), ARRAY_A);
}}}
will result in a query that is missing `post_date` since it gets ignored
by line 2332, and yields unexpected results. The resulting wrong query at
line 2623 is:
{{{
" SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_parent =
172 AND (post_mime_type LIKE 'image/%') AND wp_posts.post_type =
'attachment' AND (wp_posts.post_status <> 'trash' AND wp_posts.post_status
<> 'auto-draft') ORDER BY menu_order ASC "
}}}
Note the missing `post_date` at the end.
'''Fix'''
Rename `date` to `post_date` in line 2320.
'''Suggestion'''
Allow passing different `order` values for different `orderby` columns,
e.g. `ORDER BY post_date ASC, menu_order ASC`. Right now, the same `order`
is applied to all `orderby` columns.
This can be easily implemented without breaking backward compatibility, by
explode()'ing the `order` string using spaces so that the user can use,
e.g.:
{{{
$images = get_children(array(
'orderby' => 'menu_order post_date',
'order' => 'ASC DESC',
), ARRAY_A);
}}}
in which `ASC` applies to `menu_order` and `DESC` to `post_date`.
Cheers,
Bogdan.
--
Ticket URL: <http://core.trac.wordpress.org/ticket/19040>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list