pre_get_posts to get all posts connected to single object

Support MB Relationships pre_get_posts to get all posts connected to single objectResolved

Viewing 15 posts - 1 through 15 (of 17 total)
  • Author
    Posts
  • #11651
    Content PilotContent Pilot
    Participant

    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?

    #11659
    Anh TranAnh Tran
    Keymaster

    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.

    #11663
    Content PilotContent Pilot
    Participant
    
    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.

    #11664
    Content PilotContent Pilot
    Participant

    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.

    #11683
    Anh TranAnh Tran
    Keymaster

    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.

    #11694
    Content PilotContent Pilot
    Participant

    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.
    basic query

    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.
    altered query

    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;
        }
    
    #11702
    Anh TranAnh Tran
    Keymaster

    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');
    #11715
    Content PilotContent Pilot
    Participant

    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.

    altered

    base

    #11716
    Content PilotContent Pilot
    Participant

    base

    altered

    #11717
    Content PilotContent Pilot
    Participant
    #11746
    Anh TranAnh Tran
    Keymaster

    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.

    #11762
    Content PilotContent Pilot
    Participant

    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.

    #11765
    Content PilotContent Pilot
    Participant

    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.
    query and erorrs

    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?

    #11766
    Content PilotContent Pilot
    Participant

    d

    gg

    s

    #11767
    Content PilotContent Pilot
    Participant

    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',
            ),
        ) );
    } );
Viewing 15 posts - 1 through 15 (of 17 total)
  • You must be logged in to reply to this topic.