Symfony 1.4 + PhpBB3 session integration / phpbb3 connector

This is how I managed to connect my symfony-users with the PhpBB3-sessions. Goal is to check in a symfony-action or -template if a user is authenticated in the corresponding forum.

From here you could easily add: If there is no valid session, you could create a new one. And on each interaction with the website you could update the existing session. But this is not a MUST for me. If you need it, you might want to implement it by yourself (I marked the parts in the code with TODO) and post it in the comments or there: http://forum.symfony-project.org/index.php?t=msg&goto=98360&#msg_98360

<?php
/**
 * Integration with phpBB v3 forums
 * (c)Amir Wald 2008 - http://colnect.com
 * (c) modified by Robert Heim 2010 - http://blog.robert-heim.de
 *
 * see: http://forum.symfony-project.org/index.php/m/29883/
 */
class PhpbbIntegration
{
	// adjust these constants to your needs..
	const FORUM_URL = 'http://localhost:8046/';
	const FORUM_PATH = '/../../../../forum/';
	const DB_SERVER = 'localhost';
	const DB_USER = 'root';
	const DB_PASSWORD = '';
	const DB_DATABASE = 'phpbb3';
	const DB_PREFIX = 'phpbb';
	const ANONYMOUS = 1;
 
	private static $link = null;
	private static $cookies = null;
 
	/**
	 * Gets the link to phpBB database
	 *
	 * @return resource - a MySQL link identifier on success, throws Exception on error
	 * @author (c) Robert Heim 2010 - http://blog.robert-heim.de
	 */
	public static function getDbConnection()
	{
		if (!is_null(self::$link))
		{
			return self::$link;
		}
 
		self::$link = @mysql_connect(self::DB_SERVER, self::DB_USER, self::DB_PASSWORD);
		if (self::$link && @mysql_select_db(self::DB_DATABASE, self::$link))
		{
			return self::$link;
		}
 
		throw new Exception("getDbConnection failed. MESSAGE [[file:".__FILE__.' line:'.__LINE__.": ".mysql_error()."]]");
		return self::$link;
	}
 
	/**
	 * Execute SQL query on phpBB database
	 *
	 * @param string $sql
	 * @return resource
	 */
	public static function sqlExec($sql)
	{
		if (!($result = @mysql_query($sql, self::getDbConnection()))) {
			throw new Exception("SqlExec failed. QUERY [[$sql]] MESSAGE [[".mysql_error()."]]");
		}
		return $result;
	}
 
	/**
	 * Checks if the user is logged in to the Phpbb
	 *
	 * @param integer $user_id
	 * @return boolean - true if the user is logged in to Phpbb, false otherwise
	 * @author (c) Robert Heim 2010 - http://blog.robert-heim.de
	 */
	public static function isUserLoggedIn($user_id)
	{
		return (self::checkSession() > 0);
	}
 
	/**
	 * Validates a users session from phpBB cookies against the db.
	 *
	 * @return integer - user_id if the user is logged in to Phpbb, 0 otherwise
	 * @author (c) Robert Heim 2010 - http://blog.robert-heim.de
	 */
	public static function checkSession()
	{
		$cookies = self::readCookies(self::getConfigVal('cookie_name'));
 
		if ($cookies['user_id'] != null && $cookies['sessionId'] != null )
		{
			// check session
			$user_id = self::checkDbSession((int)$cookies['user_id'], $cookies['sessionId']);
			if ($user_id > 0)
			{
				// user is logged in and has a valid session
				return $user_id;
			}
		}
 
		// no valid session yet.
 
		// check session-key ("remember me"-feature)
		if ($cookies['sessionKey'] == null)
		{
			// key is missing
			return 0;
		}
 
		// get/create and update session within checkDbSessionKey
		$user_id = self::checkDbSessionKey($cookies['sessionKey']);
		if ($user_id <= 0)
		{
			// the session key was not found in the db
			return 0;
		}
 
		$sessionId = self::getSessionId($cookies['user_id']);
		if ($sessionId == '')
		{
			// there was no valid session and a new one was not created during the getSessionId(...)
			// so we don't have a session and the user is not logged in.
			return 0;
		}
 
		return $user_id;
	}
 
 
	/**
	 * Get a configuration value from phpBB's database
	 *
	 * @param string $name - value name
	 * @return string - the value
	 */
	private static function getConfigVal($name)
	{
		$sql = "SELECT `config_value` FROM `".self::DB_PREFIX."_config` WHERE `config_name` LIKE '$name'";
		$result = self::sqlExec($sql);
		$ar = mysql_fetch_array($result);
		return $ar['config_value'];
	}
 
	/**
	 * Gets the session_id for a user_id from the sessions-table of te phpbb3.
	 * TODO: If there is none a new session is created. Existing sessions will be updated.
	 *
	 * @param integer $user_id
	 * @return string - session_id if the user is logged in to Phpbb, '' otherwise
	 * @author (c) Robert Heim 2010 - http://blog.robert-heim.de
	 */
	private static function getSessionId($user_id)
	{
		if (!is_int($user_id) || $user_id < 1 || $user_id === self::ANONYMOUS) {
			return '';
		}
		$user_id = mysql_real_escape_string($user_id, self::getDbConnection());
 
		$sql = "SELECT * FROM `".self::DB_PREFIX."_sessions` WHERE `session_user_id`=$user_id";
		$result = self::sqlExec($sql);
 
		if (mysql_num_rows($result) <= 0) 
		{
			// no session found
			// TODO insert a new phpbb session  - see phpbb3/includes/session.php for how this should be done
			// TODO set $session_ar;
			return '';
		}
		else
		{
			$session_ar = mysql_fetch_array($result);
			// TODO update current phpbb session - see phpbb3/includes/session.php for how this should be done
			return $session_ar['session_id'];
		}
		return '';
	}
 
	/**
	 * Check user's session(s) from phpBB's database
	 *
	 * @param integer $user_id
	 * @param integer $sid session_id
	 * @return integer - user_id if the user is logged in to Phpbb, 0 otherwise
	 * @author (c) Robert Heim 2010 - http://blog.robert-heim.de
	 */
	private static function checkDbSession($user_id, $sid)
	{
		if (!is_int($user_id) || $user_id < 1 || $user_id === self::ANONYMOUS) {
			return 0;
		}
		$user_id = mysql_real_escape_string($user_id, self::getDbConnection());
		$sid = mysql_real_escape_string($sid, self::getDbConnection());
 
		$sql = "SELECT * FROM `".self::DB_PREFIX."_sessions` WHERE `session_user_id`=$user_id AND `session_id` = '".$sid."'";
		$result = self::sqlExec($sql);
		if (mysql_num_rows($result) <= 0) 
		{
			// no session found
			return 0;
		}
		#$session_ar = mysql_fetch_array($result);

		return $user_id;
	}
 
	/**
	 * Validates a users session_key with the phpBB's database
	 *
	 * @param string $sessoin_key
	 * @return integer - user_id if the key is in the db, 0 otherwise
	 * @author (c) Robert Heim 2010 - http://blog.robert-heim.de
	 */
	private static function checkDbSessionKey($session_key)
	{
		$session_key = mysql_real_escape_string($session_key, self::getDbConnection());
 
		$sql = "SELECT * FROM `".self::DB_PREFIX."_sessions_keys` WHERE `key_id`='$session_key'";
		$result = self::sqlExec($sql);
		if (mysql_num_rows($result) <= 0) 
		{
			// no session_key found
			return 0;
		}
		$session_key_ar = mysql_fetch_array($result);
 
		return (int)$session_ar['user_id'];
	}
 
	/**
	 * reads client cookies of the phpBB3
	 *
	 * @param string $phpbbCookieName
	 * @return array - $phpbbCookieName
	 * @author (c) Robert Heim 2010 - http://blog.robert-heim.de
	 */
	private static function readCookies($phpbbCookieName)
	{
		if(is_null(self::$cookies))
		{
			$sessionKey = sfContext::getInstance()->getRequest()->getCookie($phpbbCookieName.'_k');
			$user_id = sfContext::getInstance()->getRequest()->getCookie($phpbbCookieName.'_u');
			$sessionId = sfContext::getInstance()->getRequest()->getCookie($phpbbCookieName.'_sid');
			$cookies = array('sessionKey' => $sessionKey,
							'user_id' => $user_id,
							'sessionId' => $sessionId,
			);
			self::$cookies = $cookies;
		}
		return self::$cookies;
	}
 
}
This entry was posted in Software Engineering and tagged , . Bookmark the permalink.

2 Responses to Symfony 1.4 + PhpBB3 session integration / phpbb3 connector

  1. Tomás F. says:

    Hi Robert!!

    Thanks for your work Robert. I’ve seen it in the symfony forums and I really appreciate it :D. Have you continued working in the class?

    Also it would be interesting for me to know if you have found a better solution to integrate symfony 1 with a forum in the last year :)). And… in the same way… Have you migrated to symfony 2 yet? 🙂

    Thank very much!

  2. Robert Heim says:

    Hi Tomás,

    thanks for the feedback. I used it quit a while, but the project is not developed anymore. Maybe you can get a nice integration with Symfony2? Or wait for phpbb4 which is devoloped in sf2 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *