0

I have looked around and I cannot seem to find an answer to this question. There are similar questions/answers but none I have seen managed to answer this question, so I am sorry in advanced if I have missed this question if it has already been asked.

My Question is, is it possible to pull posts from a Category from another Wordpress Installation using a different database in the same server?

For example.

My main site is a Media site with various posts. The second site is one of our journalists website/blog on the same server, different database and different installation.

We would like to copy/pull his posts from "Example Category" and show that post in our wordpress pages. Using the same theme as the main and it does not redirect to the second wordpress installation. So pretty much copies the post over automatically into the Main Website.

Does having Wordpress MultiSite make things a lot easier or should we stick with single installations? We will have more than 10+ wordpress blogs in the future.

Thank You

2 Answers 2

2

Non-Multisite setup:

You need to create another instance of the WPDB Class.

$newWPDB = new wpdb('Username','password','database','localhost');
$rows = $newWPDB->get_results("you-query-here");


On WordPress Multisite:

Does having Wordpress MultiSite make things a lot easier or should we stick with single installations?

There is the switch_to_blog() function available. You will need to restore_current_blog() after getting your results.

Note that you could cache the results, for example using the Transients API, to reduce server load on future requests.

2
  • switch_to_blog() works only in multiside (same installatrion, same database). Here we have two different blogs with different databases.
    – Ralf912
    Apr 23, 2013 at 5:28
  • Yes, I was comapring/answering the part Does having Wordpress MultiSite make things a lot easier or should we stick with single installations? Edited my answer.
    – RRikesh
    Apr 23, 2013 at 5:42
0

As mentioned in the answer of RRikesh, a multiside installation make it all easier because it's the same database and you have access to it.

If you have problems connectiing to the foreign database (maybe some security restrictions or the database is not on the same server), you have to do a bit more work. In this case, you can fetch the feed, parse and store it.

Fetching the feed is a bit problematic because the feed normally returns the latests x posts (default is 10 posts). If you want to fetch a feed with all posts, you have to install a "server" plugin which modify the settings. To not disturb the normal feed behaviour, I trigger the unlimited feed with a url parameter. Let's start with the "server" plugin.

/**
 * Plugin Name: Fetch Posts Server
 * Plugin URI:
 * Description: Allow to fetch all posts in XML format from another blog
 * Version:     0.1
 * Author:      Ralf Albert
 * Author URI:  http://yoda.neun12.de
 * License:     GPLv3
 */

namespace FetchPostsServer;

add_filter(
    'query_vars',
    function( $qvars ) {
        array_push( $qvars, 'getall' );
        return $qvars;
    }
);

add_action( 'pre_get_posts', __NAMESPACE__ . '\get_all_posts_as_xml' );

function get_all_posts_as_xml( $query ) {

    if ( true === $query->is_feed ) {
        $getall = ( isset( $query->query['getall'] ) ) ? $query->query['getall'] : '';

        if ( ! empty( $getall ) ) {
            // remove the feed posts limit
            add_filter(
                'post_limits_request',
                function( $limits ) { return ''; }
            );

        }

    }

}

That's easy. At first the plugin add a query var. In the next step, the plugin hook into pre_get_posts, check if a feed is requested and check if the query var getall is set. If it is set, add a filter to remove the post limit.

If we now request a feed and pass the url parameter getall, we get all posts instead of the normally limited amount of 10 (or so).

On the "client" side, it is a bit more work. We need a cron to check for new posts, get all posts on the first run and return the stored posts if requested. I choose the options table to store the posts, I think it's the best place.

/**
 * Plugin Name: Fetch Posts Client
 * Plugin URI:
 * Description: Fetch posts in XML format from another blog
 * Version:     0.1
 * Author:      Ralf Albert
 * Author URI:  http://yoda.neun12.de
 * License:     GPLv3
 */

namespace FetchPostsClient;

// schedule event
if ( ! wp_next_scheduled( 'fetch_posts' ) ) {
    wp_schedule_event( time(), 'daily', 'fetch_posts' );
}

add_action( 'fetch_posts', __NAMESPACE__ . '\fetch_posts' );

/*
 * fetch the newest posts once a day
 */
function fetch_posts() {

    fetch_posts_as_xml( array( 'url' => 'http://wpse.tld/', 'cat' => 'uncategorized', 'return' => false ) );

}

/*
 * fetching the posts
 */
function fetch_posts_as_xml( $args, $return = false ) {

// for debugging
//add_filter( 'wp_feed_cache_transient_lifetime' , function() { return 5; } );

    // get stored posts from options
    $fetched_posts = get_option( 'fetched_posts' );

    // if we just need the stored posts, return them
    if ( true == $return || ( isset( $args['return'] ) && true == $args['return'] ) )
        return $fetched_posts;

    // prepare fetching the feed
    if ( ! function_exists( 'fetch_feed' ) )
        include_once( ABSPATH . WPINC . '/feed.php' );

    if ( ! isset( $args['url'] ) )
        return;

    $url = $args['url'];

    /*
     * other options like author, tag, etc. possible
     */
    //  add category (if present)
    if ( isset( $args['cat'] ) )
        $url = add_query_arg( array( 'cat' => $args['cat'] ), $url );

    // need the feed (rss2)
    $url = add_query_arg( array( 'feed' => 'rss2' ), $url );

// for debugging
//printf( '<p>Posts stored: %d<br>', sizeof( $fetched_posts ) );

    // if no posts are stored, this is the first run, get all posts
    if( empty( $fetched_posts ) )
        $url = add_query_arg( array( 'getall' => 1 ), $url );

    // start fetching the feed
    $rss = fetch_feed( $url );

    if ( isset( $rss->errors ) && ! empty( $rss->errors ) ) {
        // do some better error handling like logging the error
        var_dump( $rss->errors );
        return;
    }

    if ( ! is_wp_error( $rss ) ) {
        $maxitems  = $rss->get_item_quantity( -1 ); // get as much items as possible
        $rss_items = $rss->get_items( 0, $maxitems );
    }

    // parsing the feed
    foreach ( $rss_items as $item ) {

        $fetched_posts[ $item->__toString() ] = array(
            'title'     => $item->get_title(),
            'content'   => $item->get_content(),
            'permalink' => $item->get_permalink()
        );

    }

// for debugging
//printf( 'New postcount: %d</p>', sizeof( $fetched_posts ) );

    // store posts in options
    update_option( 'fetched_posts', $fetched_posts );

    // return the posts
    return $fetched_posts;

}

The plugin fetch the feed daily, parse the posts and store them in the options table. Displaying the stored posts is very easy:

$posts = FetchPostsClient\fetch_posts_as_xml( array(), true );

echo '<ol>';
array_walk(
    $posts,
    function( $post ) {
        printf(
            '<li><ul><li><a href="%s">%s</a></li><li>%s</li></ul></li>',
            $post['permalink'],
            $post['title'],
            $post['content']
        );
    }
);
echo '</ol>';

The function returns an array with each single post as array (title, permalink and content). You can place the code in a template or widget.

Remark

This is "raw" code. It needs to be optimized, some values have to be sanitized and so on. Don't use it in your production or public blog!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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