Support Forum
Support › MB Relationships › pre_get_posts to get all posts connected to single objectResolved
I have a listing of people that I am showing on the post type archive. For taxonomies I can use a simple query var with the taxonomy term to filter out the listing of all posts into the posts only inside that taxonomy. I would like to do the same thing with relationships.
Is there a built-in query var for relationships? I think that is relationship
. But then how would I use it in the URL bar? Pass a single ID?
for example - domain.com/people/?relationship=320
What I was thinking about doing is add a custom query arg then pass a single post ID then use that post ID inside a pre_get_post
filter to only show the posts related to that ID. Does that sound like a good plan?
function custom_query_vars_filter($vars) {
$vars[] .= 'relationships';
return $vars;
}
add_filter( 'query_vars', 'custom_query_vars_filter' );
function prefix_get_related_posts( $query ) {
$post_id = get_query_var('relationships');
if ( empty( $post_id ) || is_admin() ) {
return $query;
}
if( is_post_type_archive( 'poa_person' ) && $query->is_main_query() ) {
$relationship = array(
'id' => 'poa_practice_to_poa_person',
'from' => $post_id,
);
$query->set( 'relationship', $relationship );
}
return $query;
}
add_filter( 'pre_get_posts', 'prefix_get_related_posts', 10, 1);
This does not work just yet. Can you help shed some light on this query?
Hi Juanita,
You're right about the query var. And your idea of adding the query var is great. I think the only problem is using pre_get_posts
is too late. The plugin uses parse_query
hook to setup some parameter for the SQL. So you might want to change your code from pre_get_posts
to parse_query
.
function custom_query_vars_filter($vars) {
$vars[] .= 'relationships';
return $vars;
}
add_filter( 'query_vars', 'custom_query_vars_filter' );
function prefix_get_related_posts( $query ) {
$post_id = get_query_var('relationships');
if ( empty( $post_id ) || is_admin() ) {
return $query;
}
if( is_post_type_archive( 'poa_person' ) && $query->is_main_query() ) {
$query->set( 'relationship',
array(
'id' => 'poa_practice_to_poa_person',
'from' => $post_id,
)
);
}
return $query;
}
add_filter( 'parse_query', 'prefix_get_related_posts', 10, 1);
parse_query
works great. But now my styling is all jacked up. At least the query is working now. Thanks for the help.
On second look, parse_query
is throwing off the entire query so the post type archive doesn't even get the post type it is associated with. I am getting the proper related post just fine but I am loosing the post type for the entire query. It seems like I am overriding my entire query and just setting the relationship query instead of adding the two queries together.
Hi Juanita,
The parse_query
hook runs just before pre_get_posts
and there's nothing between them. See this screenshot:
https://i.imgur.com/CtLBCui.png
So, if your code works with pre_get_posts
, it should work with parse_query
. I guess the problem might come from other things.
I disabled every plugin and reverted to default WP theme to test. I am still stumped. Have a look at the two screenshots. First one is the base query where the query and query_vars match. This query assigns the post type to every other function to get things like post type archive title, etc.
Second is when the query_vars are used to alter the query. Notice how the query and query vars are different. The filtering of posts works great to show only the post that is related to 2735.
Can you add this code to your install and let me know if you are seeing the same errors?
add_action( 'parse_query', 'poa_filter_query_by_relationship', 10, 1 );
/**
* Filter the main query by using URL parameters
*
* @param object $query WP_Query.
* @return object
*
* @since 3.6.8
*/
function poa_filter_query_by_relationship( $query ) {
$id = get_query_var('relation_id');
$from = get_query_var('relation_from');
$to = get_query_var('relation_to');
if ( ! empty( $id ) && ! is_admin() && $query->is_main_query() ) {
if ( ! empty( $from ) ) {
$query->set( 'relationship',
array(
'id' => esc_attr( $id ),
'from' => intval( $from ),
)
);
var_dump($query);
} elseif ( empty( $to ) ) {
$query->set( 'relationship',
array(
'id' => esc_attr( $id ),
'to' => intval( $to )
)
);
}
}
}
add_filter( 'query_vars', 'add_query_vars' );
/**
* Add query vars to build query with URL parameters
*
* @param array $vars WP_Query variables.
* @return array
* @since 3.6.8
*/
public function add_query_vars( array $vars ) {
$vars[] = 'relation_id';
$vars[] = 'relation_from';
$vars[] = 'relation_to';
return $vars;
}
Hi Juanita,
I can't see 2 screenshots :(.
But I think the problem is the way you get query var. The get_query_var
should not be used in this situation as it gets the value from the main query. Please replace the code with:
$id = $query->get('relation_id');
$from = $query->get('relation_from');
$to = $query->get('relation_to');
Still not working even thought changed how I am getting the query_var.
Did you try running that code a post type archive? That is what I am doing and seeing part of the query being altered. Its weird. It shows the proper post type objects but doesnt have the proper values for sending the post type to things like post_type_archive_title.
Hi Juanita,
Sorry to get back late. I tried your code and created a video on that: http://recordit.co/BlAq5rhUVr. The query seems fine to me. Please take a look.
Awesome video. Thank you so much for going into so much detail. This is exactly what I am after.
I could have sworn that I saw errors on the default theme. I might have some rogue pre get posts that I need to sort out in my main plugin that is also housing the relationship fields. I will do some more digging and report back.
I am following the video EXACTLY and am still seeing errors. OMG this is so frustrating. Your video is perfect and is not throwing errors. I setup the freshest install and just installed metabox and mb relationships with custom post types built all in the same file. Made the relationships and ran the query on the default theme like your video. Still seeing the post type being stripped for certain functions like get_post_type_object. I actually think get_post_type_object is returning null since the post type is being sent as a string not an array or object. Is_scalar is exiting early for get_post_type_object.
See the screenshots. I am getting the exact same query you producing with post type being sent as a string.
Running WP 4.9.8 on Flywheel
MySQL 5.6.34
PHP 7.2 and 7.0.3
Nginx
Twenty Seventeen theme
Could that have anything to do with it?
For some reason my query is setting post type to any
. For some reason in parse_query it will change the post type any when using a tax_query
. I don't have a tax_query
nor do I have any taxonomies on these two post types.
https://developer.wordpress.org/reference/classes/wp_query/parse_query/
Search for post_type
add_action( 'parse_query', 'rel_filter_query_by_relationship', 10, 1 );
/**
* Filter the main query by using URL parameters
*
* @param object $query WP_Query.
* @return object
*
* @since 3.6.8
*/
function rel_filter_query_by_relationship( $query ) {
$id = $query->get('relation_id');
$from = $query->get('relation_from');
$to = $query->get('relation_to');
if ( ! empty( $id ) && ! is_admin() && $query->is_main_query() ) {
if ( ! empty( $from ) ) {
$query->set( 'relationship',
array(
'id' => esc_attr( $id ),
'from' => intval( $from ),
)
);
} elseif ( ! empty( $to ) ) {
$query->set( 'relationship',
array(
'id' => esc_attr( $id ),
'to' => intval( $to )
)
);
}
}
}
add_filter( 'query_vars', 'rel_add_query_vars' );
/**
* Add query vars to build query with URL parameters
*
* @param array $vars WP_Query variables.
* @return array
* @since 3.6.8
*/
function rel_add_query_vars( array $vars ) {
$vars[] = 'relation_id';
$vars[] = 'relation_from';
$vars[] = 'relation_to';
return $vars;
}
add_action( 'mb_relationships_init', function() {
MB_Relationships_API::register( array(
'id' => 'practices_to_persons',
'from' => array(
'object_type' => 'post',
'post_type' => 'practice',
'admin_column' => 'after title'
),
'to' => array(
'object_type' => 'post',
'post_type' => 'person',
'admin_column' => 'after title',
),
) );
} );