3

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.

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?

4
  • When you say p2p I keep thinking of scribu's plugin Posts 2 Posts - Is that what you are referring to?
    – GhostToast
    Aug 27, 2013 at 14:05
  • Yes that's right, sorry for not mentioning. I'll update my question.
    – eskimo
    Aug 27, 2013 at 17:29
  • When you get connected_items why use an array instead of the current $post->ID, as one would do while in a loop? Seems are you are combining the looping method of p2p and the single method, into one strange method. github.com/scribu/wp-posts-to-posts/wiki/each_connected
    – GhostToast
    Aug 28, 2013 at 20:01
  • That would get the genres for each event. What I like to do is: when on an event page, get the genres for that event (this is working) and then (still on this event page) show other events which also have one or more of these genres attached to it. The last part isn't working. I've updated my question to illustrate the problem more clearly.
    – eskimo
    Aug 29, 2013 at 7:36

2 Answers 2

0

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!
7
  • Thanks! I've figured that I can use $related = p2p_type('genres_to_events')->get_related($query, array(), 'events');. Then use a while loop just like a normal with a normal wp_query to get the related posts. I can then use your method to filter out the duplicates (I'll try that step first). Then I've got one question left; how can I use more arguments in this query (like meta_compare etc)? We're almost there! I'll try your method for removing duplicates with the $related part first and update my question if it works.
    – eskimo
    Aug 29, 2013 at 13:46
  • My previous comment was a bit stupid since I can just add that arguments to the last $args mentioned in your solution. I've combined your solution with the get_related method above and your solution works perfectly! (and I've now also learned about array_unique :-))
    – eskimo
    Aug 29, 2013 at 14:04
  • Cool. Glad that works for you!
    – GhostToast
    Aug 29, 2013 at 14:16
  • Just encountered another problem. If I use the $related method as described above, it limits the results to 10 posts. This wouldn't work in my situation, since I have hundreds of events. So I'm back to using a query with connected_type etc to get an array of the posts (but the array_unique method is still useful of course). Will update when it works...
    – eskimo
    Aug 29, 2013 at 21:07
  • 'posts_per_page' => -1 -- a limit of 10 might need overridden somewhere. Look into that.
    – GhostToast
    Aug 29, 2013 at 21:08
0

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 :-)

2
  • $connected = new WP_Query( array( 'connected_type' => 'posts_to_pages', 'connected_items' => get_queried_object(), 'nopaging' => true, ) ); -- it's all about the nopaging. github.com/scribu/wp-posts-to-posts/wiki/Basic-usage
    – GhostToast
    Aug 30, 2013 at 12:05
  • True, but then I'd still not use the function get_related... The query you're suggesting would get me the genres, then I'd have to put them in a second query to get the related festivals. get_related does that in one go, so I'm hoping I can define the function outside of the plugin's core file.
    – eskimo
    Aug 31, 2013 at 11:46

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