2

Is it possible to order custom type posts by user meta? In my custom type posts list, I am showing user name and user phone. I have user id as meta of my post and ordering works for that. However, I dont have user phone as post meta, but rather it is user meta. How can I order my posts by user phone?

Here is the code I am using to order posts by post meta:

function order_columns($vars)
{
    if (!is_admin()) {
        return $vars;
    }

    $columns = array(
        'user_id',
        'expiry_date',
        'active',
    );

    if (isset($vars['orderby']) && in_array($vars['orderby'], $columns)) {
        $vars = array_merge($vars, array('meta_key' => $vars['orderby'], 'orderby' => 'meta_value'));
    }

    return $vars;
}
Jamol
  • 3,768
  • 8
  • 45
  • 68
  • As far as I know directly (in a single query) it is not possible to order post by `user_meta`. you have to either get `user_id` in sorted manner then get post by `user_id` or save phone number in `post meta` field. hope this helps. But yes nothing is impossible in WordPress. – Raunak Gupta Feb 11 '17 at 12:47
  • @RaunakGupta Thanks for the comment. Can you tell me how I can order posts by user IDs. I can get user IDs ordered by user meta, and then how to use that for ordering posts? – Jamol Feb 11 '17 at 13:28

2 Answers2

1

As there are no direct function to order post by usermeta so you have query 2-3 times to do this.

First we have to get all the user_id form postmeta table to do this you have to write a custom function which get the user_id

function wh_get_meta_values($key = '', $type = 'post', $status = 'publish') {

    global $wpdb;

    if (empty($key))
        return;

    $r = $wpdb->get_col($wpdb->prepare("
        SELECT pm.meta_value FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
        WHERE pm.meta_key = '%s' 
        AND p.post_status = '%s' 
        AND p.post_type = '%s' ", $key, $status, $type));

    return $r;
}

Add ^^this in you functions.php file.


//getting User ID in sorted manner
$sorted_user_ids = get_users([
    'include' => wh_get_meta_values('user_id', 'your_post_type'), 
    'meta_key' => 'phone', //<- meta key by which you wnat to order
    'orderby' => 'meta_value_num',
    'order' => 'ASC',
    'fields' => 'ID'
        ]
);

if (!empty($sorted_user_ids)) {
    foreach ($sorted_user_ids as $user_id) {
        $args = [
            'post_type' => 'your_post_type',
            'meta_query' => [
                'relation' => 'AND',
                [
                    'key' => 'user_id',
                    'value' => $user_id,
                    'compare' => '=',
                ]
            ]
        ];
        $custom_query = new WP_Query($args);

        while ($custom_query->have_posts()) : $custom_query->the_post();
            ?>

            <div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
                <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
                <?php the_content(); ?>
            </div>
            <?php
        endwhile;
        wp_reset_postdata(); // reset the query
    }
}

Hope this helps!

Raunak Gupta
  • 10,412
  • 3
  • 58
  • 97
  • I need this posts on admin page posts list. I am modifying custom type posts list. How can I use your solution there? – Jamol Feb 11 '17 at 17:17
  • Ooh, then you must mentioned this on your question. And let explore the admin post listing, because I'm 'll versed on that. – Raunak Gupta Feb 11 '17 at 17:20
0

You can use function pre_get_posts to change the query and sorting method.

function ta_modify_main_query($query) {
   if ($query->is_main_query()) {
       $query->set('orderby', 'meta_value_num');
       $query->set('meta_key', '_liked');
       $query->set('order', 'DESC');
   }
}

add_action( 'pre_get_posts', 'ta_modify_main_query' );
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108