0

So I'm going to explain this the best way possible, and see if someone might be able to help me out.

Website 1 (Posts located here):

Let's say that our WordPress REST API endpoint is: https://example-1.com/wp-json/v2/posts

Since the native v2/posts endpoint doesn't support post_meta, I added support using the following:

add_filter('rest_post_query', function($args, $request) {
    $args += [
        'meta_key' => $request['meta_key'],
        'meta_value' => $request['meta_value'],
        'meta_query' => $request['meta_query'],
    ];

    return $args;
}, 99, 2);

Now, I am able to successfully query the REST API using the following endpoint: https://example-1.com/wp-json/wp/v2/posts?page=1&meta_key=original_id

I successfully get all posts that have a original_id as the post_meta over the WordPress REST API.


Website 2 (Pulling in posts from website #1):

Now, on this website I want to pull in ALL posts EXCEPT posts that have the post_meta of original_id.

So I have the following code:

$response = wp_remote_get(
    https://example-1.com/wp-json/v2/posts?page=' . $page_number . '&meta_key=original_id'
);

This pulls in ONLY the posts with the original_id post_meta.

Question:
How would I be able to do the opposite of that wp_remote_get call? Pull in all posts except posts that have original_id as the post_meta.

Since I added meta_query support to the REST API, how would I be able to utilize that?

1 Answer 1

0

One way that comes to my mind is to define your own custom routes for the API, allowing it to send results based on the route or use the same route with different GET params.

OR based on the way you're going with, you could probably send some GET params to the url and do things based on them by getting the params from $request and have conditions based on the params.

Something like:

add_filter('rest_post_query', function($args, $request) {
    $queryParams = $request->get_query_params();
    $want_meta = isset( $queryParams['want_the_meta_ones'] ) AND $queryParams['want_the_meta_ones'] == 'yes';
    if( $want_meta ){
        $args += [
            'meta_key' => $request['meta_key'],
            'meta_value' => $request['meta_value'],
            'meta_query' => $request['meta_query'],
        ];
    } else {
        $args += [
            'meta_key' => $request['meta_key'],
            'meta_compare' => 'NOT EXISTS',
        ];
    }
    return $args;
}, 99, 2);

Mixed with:

$response = wp_remote_get(
    'https://example-1.com/wp-json/v2/posts?page=' . $page_number . '&meta_key=original_id&want_the_meta_ones=yes'
);

or:

$response = wp_remote_get(
    'https://example-1.com/wp-json/v2/posts?page=' . $page_number . '&meta_key=original_id&want_the_meta_ones=no'
);

Update 1: if we want the original query to be untouched in case there is no specefic url param, this is how we do it:

add_filter('rest_post_query', function($args, $request) {
    $queryParams = $request->get_query_params();
    $meta_action = isset( $queryParams['meta_action'] ) AND $queryParams['meta_action'];
    if( $meta_action ){
        if( $meta_action == 'include_meta' ){
            $args += [
                'meta_key' => $request['meta_key'],
                'meta_value' => $request['meta_value'],
                'meta_query' => $request['meta_query'],
            ];
        } elseif( $meta_action == 'exclude_meta' ) {
            $args += [
                'meta_key' => $request['meta_key'],
                'meta_compare' => 'NOT EXISTS',
            ];
        }
    }
    return $args;
}, 99, 2);

this way if the param meta_action is not set to either include_meta or exclude_meta, the main query is untouched. I think include_meta and exclude_meta what they do is kind of self-explanatory. I also added some gaps in code and did it in the most basic way so you could get the idea and expand it based on your needs. the call would look like this:

$response = wp_remote_get(
    'https://example-1.com/wp-json/v2/posts?page=' . $page_number . '&meta_key=original_id&meta_action=include_meta'
);
4
  • Thanks so much @Sadoo, I will attempt this method, is there a way that I can add a conditional so I have minimum impact on the native wp-json/v2/posts route, such that if I don't pass in a meta_key or want_the_meta_ones query strings in the route, that there is no impact on the original wp-json/v2/posts endpoint.
    – Tripp
    Jul 17, 2022 at 21:27
  • sure thing. if we don't change the $args we are not causing any changes. let me update the code for you.
    – Sadoo
    Jul 17, 2022 at 21:30
  • Thanks so much @Sadoo, this works well! Looking forward to the updated code, thanks so much! I will upvote this post.
    – Tripp
    Jul 17, 2022 at 21:33
  • Updated it right there right then :)
    – Sadoo
    Jul 18, 2022 at 0:10

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.