Development

HowToIntegrateWordPressAndBbPressWithSymfony

You must first sign up to be able to contribute.

How To Integrate WordPress and bbPress with symfony

Based on a forum post

This article is based on my experience of creating the website http://hi.edgehill.ac.uk/. A bit of background to the site - it's aimed at people who've applied to the University to provide them with an insight to student life. It provides forums (bbPress), blogs from current students (WordPress MU) and other content features (symfony). The whole project has taken about 4-8 man weeks.

Symfony provides the core functionality and ties everything together. Users register via the site with data pulled in from a legacy Oracle database holding information about applicants - this ensures that only real applicants can register. Once users are approved (either self registering or automatically via the invite link we sent through a mail merged email) they are added to the main University LDAP server. This allows (selected) staff and students to log in with their normal username/password rather than having to register again.

Integration with WordPress/bbPress is in three main areas:

Login

All logins are done though symfony, login forms in *Press either submit their data to a symfony action or a (*Press) filter intercepts the request and redirects them to the symfony login page. Once they are logged in to a symfony session they can go back to *Press and will be automatically logged in. The idea is to replace functions provided in the pluggable.php file. I replace bb_check_login(), bb_current_user() and bb_logout() in bbPress and similar functions in WordPress. I use database storage for sessions and query this to determine if the user is logged in. If symfony says the user exists but *Press doesn't have a corresponding user then we add them to the database.

<?php
function get_currentuserinfo() {
    global $current_user, $wpdb;
    $session_id = $_COOKIE['eh_hi'];
    $sql = "SELECT * FROM hi_symfony.session WHERE sess_id='$session_id'";
    $session = $wpdb->get_row($sql);
    preg_match('|s:8:"username";s:\d+:"(\w+)"|', $session->sess_data, $matches);
    $user_login = $matches[1];
    if (!$wpdb->get_row("SELECT * FROM $wpdb->users WHERE user_login = '$user_login'") && $user_login)  { symfony_create_user($user_login); }

    if ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST )
        return false;

    if ( ! empty($current_user) )
        return;
    wp_set_current_user(0, $user_login);
}
?>

Profile information exchange

There are times when we want to access symfony user information from *Press and vice versa. This is done by directly querying the database of the other app. Using symfony it's easy - I created a schema.yml from the existing bbPress database and generated the model allowing me to directly access information using Propel methods. The other way round is only a little more tricky. bbPress provides its own user meta storage but since all user management is being done via symfony it made sense to just ignore it and query the meta information from my own table. I have a function that returns meta information for a given user/key combination and *Press filters are added to insert it into the appropriate place. For example, if users specify a nickname for the forum we want to show that rather than their username so we create a bbPress plugin:

<?php
function bb_use_display_name( $name, $id ) {
    $user = bb_get_user( $id );
    $nickname = symfony_user_meta($id, 'nickname');
    $display_name = $nickname ? $nickname : $user->user_login;
    return $display_name;
}

add_filter( 'topic_last_poster', 'bb_use_display_name', 1, 2 );
add_filter( 'topic_author', 'bb_use_display_name', 1, 2 );
add_filter( 'get_post_author', 'bb_use_display_name', 1, 2 );
add_filter( 'get_user_name', 'bb_use_display_name', 1, 2 );
?>

Now everywhere we would normally show a username, we show the nickname.

RSS Feeds

The final key integration between symfony and bbPress/WordPress makes extensive use of sfFeed2Plugin which came along right on cue! In parts of the site where we want to include things like the latest blog or forum posts, I insert a component to load the data from *Press. Rather than querying the table directly, which would certainly be possible, I instead download an RSS feed and use information from that. This means that I don't have to reimplement the URL writing rules in symfony - *Press already knows what link should be provided for each item in the feed. Components are cached for between 10 minutes and a couple of hours to reduce the load time but keep the site fresh.