How would I use pre_get_posts to query another site for posts in my multisite network?

OK so for reference I ended up actually using switch_to_blog() and restore_current_blog(). I found no references whatever for querying multiple tables (except writing my own JOIN-statements) when followed the source code for the action pre_get_posts.

A lot of advice was given to skip restore_current_blog() to save CPU-cycles but when I checked the source code for this I saw that it would cause a huge memory problem since the main thing restore_current_blog() does is to pop the latest inserted object in a global array and this array would grow hugely with each switch_to_blog() that one does not do a restore_current_blog() on.

Please feel free to check the source code and also see @user42826’s answer regarding this at https://wordpress.stackexchange.com/a/123516/14820.

For those who are interested, I ended up with transients both for the site-list and for the result to save both CPU-cycles and DB performance. I only needed data to be updated if it were stale (15 minutes or more of age). Only relevant bit of function included below:

$site_transient = get_site_transient( 'multisite_site_list');
if ($site_transient == false || LL_USE_TRANSIENTS == false) {
    $using_site_transient = false;

    // no cache available
    global $wpdb;

    // TODO: get prefix for wp tables
    $site_list = $wpdb->get_results($wpdb->prepare('SELECT * FROM nw_blogs WHERE public = %d AND deleted = %d ORDER BY blog_id', 1, 0));

    // set transient
    set_site_transient('multisite_site_list', $site_list, LL_TRANSIENT_EXPIRES);

} else {
    //log_msg("SITELIST - Transient found, using cached query..");
    $site_list = $site_transient;
    $using_site_transient = true;
}

//log_msg("$id - get_posts_from_network | tags: " . implode(",", $tags) . " | tag_slug__and: $lang_full");

$start = microtime(true);

// get blogpost transient, if existing
$post_transient = get_site_transient( 'limelight_recent_posts_' . $hash);

// if not, do query and save result as a transient
if ($post_transient == false || LL_USE_TRANSIENTS == false) {
    $using_post_transient = false;
    $blogposts = array();

    foreach ($site_list as $site) {
        switch_to_blog($site->blog_id);
        $posts = get_posts(array(
            'post_status' => 'publish',
            'orderby' => 'date',
            'order' => 'desc',
            'tag' => implode(",", $tags),
            'tag_slug__and' => array($lang_full)
        ));

        //log_msg("$id - get_posts_form_network | at site: $site->blog_id");

        foreach ($posts as $post) {

            //log_msg("$id - get_posts_form_network | at site: $site->blog_id | got post!");

            $post->human_post_date = human_time_diff(get_post_time('U', false, $post->ID), current_time('timestamp')) . ' ' . __('ago', 'limelight');

            if (isset($tagline_metabox)) {
                $meta = get_post_meta($post->ID, $tagline_metabox->get_the_id(), TRUE);
                $post->tagline = $meta['tagline_text'];
            }

            if (!isset($post->tagline) || $post->tagline == '')
                $post->tagline = substr($post->post_title, 0, 20) . '..';

            $post->post_date_timestamp = strtotime($post->post_date);           

            //$post->blog_id = $site->blog_id;
            $post->blog_name = get_bloginfo('name');
            $post->blog_url = get_bloginfo('wpurl');
            $post->permalink = get_permalink($post->ID);
            $post->author_name = get_userdata($post->post_author)->display_name;
            //$data = get_userdata($post->post_author);

            $blogposts[] = $post;
        }
        restore_current_blog();
    }

    // sort blogposts by post_date_timestamp, descending
    array_sort_by_obj($blogposts, 'post_date_timestamp', SORT_DESC);

    // pick five latest posts
    if (sizeof($blogposts) > 5) {
        $posts = array();
        for ($i = 0; $i <= 4; $i++) {
            $posts[$i] = $blogposts[$i];
        }
        $blogposts = $posts;
    }

    // set transient
    if (LL_USE_TRANSIENTS)
        set_site_transient('limelight_recent_posts_' . $hash, $blogposts, LL_TRANSIENT_EXPIRES);

Leave a Comment