Jamol
Jamol

Reputation: 3918

Wordpress: Order posts by user meta

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;
}

Upvotes: 2

Views: 1488

Answers (2)

Magnus TechApple
Magnus TechApple

Reputation: 116

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' );

Upvotes: 0

Raunak Gupta
Raunak Gupta

Reputation: 10809

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!

Upvotes: 1

Related Questions