I am trying to get all products from the wpsc-product post type and then display them by a custom meta field called release_date_year. However, it doesn’t appear to be ordering my posts by this custom meta value.
I have read through countless blog posts, support posts on the WordPress forums and a lot of questions and answers here on WordPress Answers. However, I could not find a solution to my issues.
Here is the code that I am using to get the products and then order them by a custom meta field. Ignore the each_connected argument as that is for the plugin Posts to Posts by Scribu. A quick note: I have also tried remove the each_connected part to see if it fixed the issue, but as I suspected, it didn’t change a thing.
It appears as though the below code gets the products okay, that’s not the issue. The issue seems to be that they are being ordered by the date they were published and not the custom meta field value which is a numeric value.
$products = new WP_Query(array(
'post_type' => 'wpsc-product',
'nopaging' => true,
'meta_key' => 'release_date_year',
'each_connected' => array(
'post_type' => 'artists',
'nopaging' => true,
),
'suppress_filters' => false,
'orderby' => 'meta_value_num',
'order' => 'asc',
));
I then looked at what queries were being run and the following is the result:
SELECT wp_posts.* FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND wp_posts.post_type = 'wpsc-product' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') AND wp_postmeta.meta_key = 'release_date_year' GROUP BY wp_posts.ID ORDER BY wp_posts.menu_order, wp_posts.post_date DESC
Now is it just me or should the ‘ORDER BY’ part of my query have wp_postmeta.meta_key in it? Because it looks to me it’s ordering by the menu order and then the post date descending. The other weird thing is that I am also seeing posts ordered descending instead of ascending.
Like I said, I also tried using meta_query in my WP_Query query as I am using WordPress 3.1 using the following code and it was still ordering posts by post_date:
$products = new WP_Query(array(
'post_type' => 'wpsc-product',
'nopaging' => true,
'meta_key' => 'release_date_year',
'meta_query' => array(array(
'key' => 'release_date_year',
'type' => 'NUMERIC'
)),
'each_connected' => array(
'post_type' => 'artists',
'nopaging' => true,
),
'suppress_filters' => false,
'orderby' => 'meta_value',
'order' => 'desc',
));
Have I incorrectly formatted my WP_Query statement or is something else at play here? I have also confirmed there is data in the wp_postmeta table and there are values for each product there.
Update and Solution
After some messing around, I found the culprit. A plugin called ‘Post Types Order’ which was modifying my WordPress queries and hence causing the suppress_filters argument to be completely ignored, amongst other things like orderby.
See my answer below.
The plugin ‘Post Types Order‘ was the culprit. As Scribu pointed out above the plugin is filtering the Raw SQL query which it shouldn’t be doing. As a result, the argument ‘suppress_filters‘ wasn’t stopping the query being modified and the ‘orderby‘ argument was being completely ignored.
As to how this behavior can be stopped, I’m not sure. I solved my issue by disabling the plugin as it wasn’t even being used. However, you can set the order of your custom post type menus in your register_post_types code instead, using the ‘menu_position‘ argument which decides where the menu will be placed.
Documentation for ordering your post types in the WordPress admin menu can be found here in the official WordPress documentation.
The lesson learned here is that you should always assume that a plugin has broken something, especially if you are using code from the official documentation that works.
It looks like your ‘orderby’ parameter is completely ignored.
Try setting
'suppress_filters' => true
to make sure there’s no interference.