1

I have a table named views.
this table has "post id" and "views"
I've added views for each post to my custom post type rest-API.
I want to order the rest-API posts by views.
I've found this topic that shows how to order the rest-API posts by meta value:
https://stackoverflow.com/questions/44783932/wp-rest-api-orderby-meta-value
but I want to order by a field that's not in the postmeta table.
Please tell me how can I do this.

1 Answer 1

1

This is the solution in the mentioned link if we want to use meta value to order the rest API content:

// Add meta your meta field to the allowed values of the REST API orderby parameter
add_filter(
    'rest_' . $post_type . '_collection_params',
    function( $params ) {
        $params['orderby']['enum'][] = 'YOUR_META_KEY';
        return $params;
    },
    10,
    1
);

// Manipulate query
add_filter(
    'rest_' . $post_type . '_query',
    function ( $args, $request ) {
        $order_by = $request->get_param( 'orderby' );
        if ( isset( $order_by ) && 'YOUR_META_KEY' === $order_by ) {
            $args['meta_key'] = $order_by;
            $args['orderby']  = 'meta_value'; // user 'meta_value_num' for numerical fields
        }
        return $args;
    },
    10,
    2
);

But I want to order the rest API contents by a field that's not in the meta table.

the table structure:

id views
-- -----
1   5
2   2
3   20
4   1

I want to sort the rest API posts descending by views in this table.
to do this I've edited Manipulate query section so I've created an array that has ids sorted by views. (to do the sort I've used the solution in this post)
then I've used post__in in args with the array that I've created before as its parameter and then I've used post__in as orderby parameter:

// Manipulate query

add_filter(
    'rest_' . $post_type . '_query',
    function ( $args, $request ) {
        //create an array that have ids that are sorted by views
        global $wpdb;   
        $post_views = $wpdb->get_results( $wpdb->prepare("SELECT id, views FROM " . $wpdb->prefix . "mytable") );
        $views = array_column($post_views, 'views');
        array_multisort($views, SORT_DESC, $post_views);
        $most_viewd = array_column($post_views, 'id');  
    
        $order_by = $request->get_param( 'orderby' );
        if ( isset( $order_by ) && 'views' === $order_by ) {
            $args['post__in'] = $most_viewd;
            $args['orderby']  = 'post__in';
        }
        return $args;
    },
    10,
    2
);
5
  • This isn't working for me. I've got a meta field by which I'd like to order, but the API returns this: "orderby":"orderby is not one of author, date, id, include, modified, parent, relevance, slug, include_slugs, title, and menu_order."
    – MastaBaba
    Jan 16, 2023 at 19:27
  • @MastaBaba did you add value to $post_type?
    – Sadegh
    Jan 18, 2023 at 11:47
  • Yes, I did. I added the filter within add_action('rest_api_init', function(){}), but also tried it outside. No difference.
    – MastaBaba
    Jan 18, 2023 at 13:49
  • 1
    @MastaBaba it works with posts or custom post type or pages. for example you can use: rest_post_query or rest_custom_post_type_name_query
    – Sadegh
    Jan 19, 2023 at 15:04
  • The particular case I needed this for is no longer relevant. But, I managed to get a filter on the REST API working for another case. So, must have made a typo of some sort.
    – MastaBaba
    Jan 22, 2023 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.