0

I have a CPT called service and a CPT called partner_request. The partner_request CPT will have post meta fields recipient_id and service_id and will have a custom post status of pending or accepted. I want to use WP_Query to retrieve a list of services that are partners with the service being viewed. The posts included in the results need to have a partner_request with a recipient_id or service_id equal to the original service's ID and a post_status of accepted. I am aware that you can use add_filter('posts_join') to add a join statement to a query. In my opinion, this looks sloppy and it would be easier to manage the code if I could use a join query within the WP_Query arguments, sort of in the same way you would use meta queries.

In the function I have that lets a user send a partner_request to another service, I make sure that no other partner_request posts between the services exist. Here is how I do that:

$request_atts = array(
    'post_type' => 'partner_request',
    'post_status' => array('pending', 'accepted'),
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'relation' => 'AND',
            array(
                'key' => 'recipient_id',
                'value' => 94
            ),
            array(
                'key' => 'service_id',
                'value' => 95
            )
        ), 
        array(
            'relation' => 'AND',
            array(
                'key' => 'recipient_id',
                'value' => 95
            ),
            array(
                'key' => 'service_id',
                'value' => 94
            )
        )

    )
);
$request_query = new WP_Query($request_atts);
if($request_query->have_posts()){
    //A request already exists
} else {
    //Send the request
}

So using the information above, is there a way to add a join clause to a WP_Query without filters?

$partner_atts = array(
    'post_type' => 'service',
    //Could a join that determines partners go here?
);

$partner_query = new WP_Query($partner_atts);
if($partner_query->have_posts()){
   //Display a list of partners
}
  • what does it even means "looks sloppy"? to whom exactly? We usually are not interested here in whatever fancy (or not) coding trends anyone follows as long as the code is correct and do not have adverse side effects. After all, this is a wordpress dvelopment site, not a code review site. – Mark Kaplun May 17 '18 at 4:44
  • 1
    ... but what sloppy here is the DB structure. If you want to use high level DB APIs you need to use wordpress storage conventions. Once the conventions are not followed, you are going to have to do sloppy things one way or another – Mark Kaplun May 17 '18 at 4:46
0

No. There isn't. The only way to add custom joins to a WordPress query is through the posts_join filter or posts_clauses filter, which contains all the parts of the query.

Those filters receive the WP_Query object as a parameter though, which allows you to create custom arguments for WP_Query that will affect the query.

function wpse_303758_posts_join( $join, $query ) {
    if ( $query->get( 'custom_arg' ) === true ) {
        $join .= " LEFT JOIN my_table ON $wpdb->posts.ID = my_table.post_id";
    }

    return $join;
}

With that filter the JOIN will be added to the query if custom_arg is true in WP_Query:

$query = new WP_Query( array(
    'custom_arg' => true,
) );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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