posts2posts query using connected_items array issue

My setup is as follows

I hava a custom post type named ‘events’ and a custom post type named ‘genres’ which I link with scribu’s Posts2Posts plugin. Each event can have multiple genres linked to it.

Read More

What I would like to do

On an event page, I’d like to show other, related, events based on the genres the current event has.

What I think I should do

  1. Run a query which gets all the genres IDs of the current event
  2. Pass these IDs in a second query which finds all the events which have one or more of these genres linked to it

I have a p2p query which I’d like to output all events which have one AND / OR more of the given genres in connected_items. I pass them as an array, just like in the documentation.

To illustrate my outcome, lets say that

  • event1 has linked genres with post ids 1240, 1241, 1242 and 1250
  • event2 has linked genres with post ids 1240, 1241 and 1260
  • event3 has linked genres with post ids 1241 and 1242

In the first query I get all the genre IDs, this works.

The second query which gets all the events with the given genres (I pass them as an array):

$args = array(
        'connected_type' => 'genres_to_events',
        'connected_items' => array(1240,1241,1242),
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );

$query = new WP_Query($args);

The thing is that the output checks for each connection in the array, and therefor the output of the query is:

  • event1
  • event1
  • event1
  • event2
  • event2
  • event3
  • event3

But I’d like to output each event once based on if it has one or more of the genres connected to it. I don’t think this is explained in the documentation, any ideas?

Related posts

2 comments

  1. Ah I think I understand. I think what you should do with your first loop, is get the connected genres as you say. Then you wish to get all events that are related to those, so you should gather only the IDs (collect them in one array) in a loop, and then use array_unique() to remove all the duplicates. Use this clean array in a loop to get just those posts then. Make sense?

    So, something like this might work:

    $args = array(
            'connected_type' => 'genres_to_events',
            'connected_items' => array(1240,1241,1242),
            'post_status' => 'publish',
            'posts_per_page' => -1,
        );
    
    $query = new WP_Query($args);
    
    $connected_out = array();
    
    while($query->have_posts()) : $query->the_post();
        $connected_out[] = $post->ID;
    endwhile;
    
    $connected_out = array_unique($connected_out);
    wp_reset_query();
    
    $args = array(
        'post__in' => $connected_out;
    );
    
    $query = new WP_Query($args);
    // go!
    
  2. I’m posting this as an answer since it partially is and because I need some more characters than available in the comments. Hope that’s OK :-).

    So I’ve found the posts_per_page issue after reading this post.

    It’s possible to pass arguments to the get_related function, although it seems like you’d have to modify the p2p core. What I did was add my own get_related function, named my_get_related.

    Code is as follows:

    public function my_get_related( $item, $extra_qv = array(), $output = 'raw' ) {
            $extra_qv['fields'] = 'ids';
    
            $connected = $this->get_connected( $item, $extra_qv, 'abstract' );
    
            $additional_qv = array( 'p2p:exclude' => _p2p_normalize( $item ), 'posts_per_page' => -1 );
    
            return $this->flip_direction()->get_connected( $connected->items, $additional_qv, $output );
        }
    

    I’ve added this in wp-content/plugins/posts-to-posts/core/directed-connection-type.php (the original get_related function is on line 94).

    You can see the 'posts_per_page' argument added, more can be easily added by separating them by commas.

    Now I still have one question: how do I declare this function outside of the p2p core file? I don’t want to add it there since it could backfire when updating the plugin. I’d like to add it to my functions.php (I use the Roots theme so it will be in some other file than functions.php but it’s the same as putting it there since the file I’ll put it in is an include of functions.php).

    I’ve tried public function my_get_related... and add_action('p2p_init', 'my_get_related') but that doesn’t work.

    Any ideas on how to add this function outside of the core?

    I think that after that, the problem is finally solved 🙂

Comments are closed.