Page 1 of 1

Using phpBB login for other parts of a site

Posted: Wed Oct 06, 2004 2:59 am
by JayBird
I am currently developing a site that currently only has a forum. There are around 500 memebers already.

Now, i am building a whole site, of which, the forum is going to be part of.

There will be many sections of the site where users will need to login, but i don't wanna have separate logins for the forum and site.

Is there any tutorials that explain how to do this or can anyone give me advice?

Cheerz

Mark

Posted: Wed Oct 06, 2004 3:05 am
by feyd
I've done this in two ways:

Using their tables way, which is dirty, but easier to set up. Or their way, which requires including a bunch of their functionality (mostly through common.php) like using session_pagestart() and init_userprefs() .. then just need the login form switchable on your pages.. :)

will also need to parse every url through their append_sid() functions.. ;)

Posted: Wed Oct 06, 2004 3:07 am
by JayBird
Im guessing i will be able to utilise the user groups too, like admin and Mods etc

Posted: Wed Oct 06, 2004 3:24 am
by feyd
correct.. all the constants, language files, board configuration, userdata, and user authorization information is easily accessed once you include common.php..

pretty much, all you need is

Code: Select all

define('IN_PHPBB', true);
$phpbb_root_path = '';
include($phpbb_root_path . 'extension.inc');
include($phpbb_root_path . 'common.'.$phpEx);

$userdata = session_pagestart($user_ip, PAGE_YOURPAGENAME);
init_userprefs($userdata);
If you create your own page names, you'll either need to hack a dynamic paging information system (for viewonline.php and admin/index.php) to correctly show the user locations. If you'd like, I can post some of my code from my modification to that and explain how it works.

Posted: Wed Oct 06, 2004 5:48 am
by JayBird
feyd wrote:...If you'd like, I can post some of my code from my modification to that and explain how it works.
That would be great if you could buddy

Posted: Wed Oct 06, 2004 7:11 am
by m3mn0n
I've never actually done this before either, so that would be very valuable information to me also. :)

Posted: Wed Oct 06, 2004 7:25 am
by feyd
note: this is in reference to phpBB 2.0.10, and that line numbers may vary wildly, as my version has been significantly altered.
note: I had to alter the code slightly for posting, so beware that the code may not fully run without some modification right off the bat.


okay.. here's an attempt to explain what I changed in phpbb to have much better page information:

function session_pagestart
this function was altered to the following:

Code: Select all

function session_pagestart($user_ip, $thispage_id, $extra_data = null)
As you can see, the last argument was added. I altered the session table to have an extra field of type INT(10) UNSIGNED, as well as changing session_page to INT(10) UNSIGNED. These were changed such that they could be useful references to data from a table, which I'll get to shortly. The update query in session_pagestart() was altered to:

Code: Select all

$sql = "UPDATE " . SESSIONS_TABLE . " 
						SET session_time = $current_time, session_page = $thispage_id, session_page_data = " . ($extra_data !== null ? (int)$extra_data : 'NULL') . "
						WHERE session_id = '" . $userdataї'session_id'] . "'";
All pages were updated for the new calls to the altered function. Pages that have differing contexts were changed to things similar to

Code: Select all

//
// Start session management
//
$userdata = session_pagestart($user_ip, PAGE_VIEWTOPIC, $topic_id);
init_userprefs($userdata);
//
// End session management
//
where $topic_id is the topic id number being viewed. This has baring on the page information table, details follow.

page information table

Code: Select all

CREATE TABLE `bb_pagesinfo` (
  `pageinfo_id` int(10) unsigned NOT NULL auto_increment,
  `pageinfo_page_const` varchar(50) NOT NULL default '',
  `pageinfo_location` varchar(50) NOT NULL default '',
  `pageinfo_admin` tinyint(1) unsigned NOT NULL default '0',
  `pageinfo_url_hook` varchar(50) default NULL,
  `pageinfo_url_add` varchar(100) default NULL,
  PRIMARY KEY  (`page_id`),
  KEY `pageinfo_page_const` (`pageinfo_page_const`)
) TYPE=MyISAM;
pageinfo_page_const references the pages table:

Code: Select all

CREATE TABLE `bb_pages` (
  `page_id` int(10) unsigned NOT NULL default '0',
  `page_const_name` varchar(50) NOT NULL default '',
  `page_name` varchar(100) default NULL,
  `page_lang` int(10) NOT NULL default 0,
  KEY `page_id` (`page_id`,`page_const_name`,`page_name`,`page_lang`)
) TYPE=MyISAM;
The constants file was updated to extract the page_id -> page_const_name matches, so we can use the constant names throughout still.

Adding pages now was a process of inserting 1-2 entries in the pageinfo table, and 1 entry for each language installed into the pages table. Pageinfo entries look similar to this:

Code: Select all

INSERT INTO `bb_pagesinfo` VALUES (1, 'Forum_index', 'PAGE_FORUMS', 'forums', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (2, 'PAGE_POSTING', 'viewtopic', 1, 'POST_TOPIC_URL', NULL);
INSERT INTO `bb_pagesinfo` VALUES (3, 'PAGE_POSTING', 'forums', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (4, 'PAGE_LOGIN', 'index', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (5, 'PAGE_SEARCH', 'search', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (6, 'PAGE_PROFILE', 'forums', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (7, 'PAGE_PROFILE', 'profile', 1, 'POST_USERS_URL', 'mode=viewprofile');
INSERT INTO `bb_pagesinfo` VALUES (8, 'PAGE_VIEWONLINE', 'viewonline', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (9, 'PAGE_VIEWMEMBERS', 'memberlist', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (10, 'PAGE_PRIVMSGS', 'privmsg', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (11, 'PAGE_FAQ', 'faq', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (12, 'PAGE_VIEWFORUM', 'viewforum', 0, 'POST_FORUM_URL', NULL);
INSERT INTO `bb_pagesinfo` VALUES (13, 'PAGE_VIEWTOPIC', 'viewtopic', 1, 'POST_TOPIC_URL', NULL);
INSERT INTO `bb_pagesinfo` VALUES (14, 'PAGE_VIEWTOPIC', 'forums', 0, NULL, NULL);
INSERT INTO `bb_pagesinfo` VALUES (15, 'PAGE_POSTINGNEW', 'viewforum', 1, 'POST_FORUM_URL', NULL);
INSERT INTO `bb_pagesinfo` VALUES (16, 'PAGE_POSTINGNEW', 'forums', 0, NULL, NULL);
Some of these require some custom processing on the viewonline pages. So their to know which ones need custom processing, their entry linkage in the pages table for their name is set to NULL.

viewonline.php
The following function was added to auth.php

Code: Select all

function getPages($user_level)
{
	global $db, $lang, $board_config, $phpbb_root_path, $phpEx;
	static $ary = null;		//	promote caching of the page data
	
	if($ary === null)
	{
		$ary = array();
		$is_admin = (int)($user_level == ADMIN || $user_level == MOD);
		$sql = 'SELECT page_name, page_const_name, pageinfo_location, pageinfo_url_hook, pageinfo_url_add FROM ' . PAGEINFO_TABLE . ', ' . PAGES_TABLE . ' WHERE pageinfo_page_const = page_const_name AND page_lang = ' . LANGID . ' AND pageinfo_admin <= ' . $is_admin . ' ORDER BY page_const_name' . ($is_admin ? ', page_admin DESC' : '' );
		$query = $db->sql_query($sql);
		
		if($query === false)
		{
			message_die(GENERAL_ERROR,'','',__LINE__,__FILE__,$sql);
		}

		$errormsg = '';

		while($row = $db->sql_fetchrow($query))
		{
			if($rowї'page_name'] !== null && !isset($langї$rowї'page_name']]))
				$errormsg .= (!empty($errormsg) ? "\n" : '<ul style="text-align:left">') . '<li>' . $board_configї'default_lang'] . 'ї' . var_export($rowї'page_const_name'],true) . '] is not defined.</li>';

			if(!is_readable($phpbb_root_path . $rowї'pageinfo_location'] . '.' . $phpEx))
				$errormsg .= (!empty($errormsg) ? "\n" : '<ul style="text-align:left">') . '<li>' . var_export($rowї'pageinfo_location'] . '.' . $phpEx,true) . ' was not found or is unreadable.</li>';

			if(!defined($rowї'page_const_name']))
				$errormsg .= (!empty($errormsg) ? "\n" : '<ul style="text-align:left">') . '<li>' . var_export($rowї'page_const_name'],true) . ' is not defined.</li>';

			if($rowї'pageinfo_url_hook'] === '' || ($rowї'pageinfo_url_hook'] !== null && !defined($rowї'pageinfo_url_hook'])))
				$errormsg .= (!empty($errormsg) ? "\n" : '<ul style="text-align:left">') . '<li>' . var_export($rowї'pageinfo_url_hook'],true) . ' is not defined or invalid.</li>';

			if($rowї'pageinfo_url_add'] === '')
				$errormsg .= (!empty($errormsg) ? "\n" : '<ul style="text-align:left">') . '<li>' . var_export($rowї'pageinfo_url_add'],true) . ' is invalid.</li>';

			if(!isset($aryї$rowї'page_const_name']]))
			{
				$aryї] = $row;
			}
		}
		
		if(!empty($errormsg))
		{
			$ary = null;
			message_die(GENERAL_ERROR,$errormsg . '</ul>','Page list errors',__LINE__,__FILE__,$sql);
		}
		elseif(empty($ary))
		{
			message_die(GENERAL_ERROR,'Unable to load page list.','',__LINE__,__FILE__,$sql);
		}
	}

	//echo '<pre style="text-align:left">' . htmlentities(var_export($ary,true),ENT_QUOTES) . '</pre>';
	return $ary;
}
The viewonline script was altered like so:

Code: Select all

//	Get pages data
//
$pages_ary = getPages($userdataї'user_level']);
$page_count = sizeof($pages_ary);
$is_admin = ($userdataї'user_level'] == ADMIN || $userdataї'user_level'] == MOD);

//
// Get auth data
//
$is_auth_ary = array();
$is_auth_ary = auth(AUTH_VIEW, AUTH_LIST_ALL, $userdata);

//
// Get user list
//
$sql = "SELECT u.user_id, u.username, u.user_allow_viewonline, u.user_level, s.session_logged_in, s.session_time, s.session_page, s.session_page_data, s.session_ip
	FROM ".USERS_TABLE." u, ".SESSIONS_TABLE." s
	WHERE u.user_id = s.session_user_id
		AND s.session_time >= ".( time() - 300 ) . "
	ORDER BY u.username ASC, s.session_ip ASC";

Code: Select all

$found = false;
		for($x = 0; !$found && $x < $page_count; $x++)
		{
			$page =& $pages_aryї$x];
			if($found = ($rowї'session_page'] == constant($pageї'page_const_name'])))
			{
				if($pageї'page_name'] === null)
				{
					switch(constant($pageї'page_const_name']))
					{
						case PAGE_VIEWFORUM:
							$location = $forum_dataї$rowї'session_page_data']];
							break;
						
						case PAGE_VIEWTOPIC:
							$db->sql_query('SELECT forum_id FROM ' . TOPICS_TABLE . ' WHERE topic_id = ' . intval($rowї'session_page_data']) . ' LIMIT 1');
							if(!$db->sql_numrows())
							{
								message_die(GENERAL_ERROR, 'Topic_post_not_exist');
							}
							else
							{
								$data = $db->sql_fetchrow();
								$location = $forum_dataї$dataї'forum_id']];
								$db->sql_freeresult();
							}
							break;
						
						case PAGE_POSTINGNEW:
							$location = sprintf( $langї'Posting_new_message'], $forum_dataї$dataї'forum_id']] );
							break;
					}
				}
				else
				{
					$location = $pageї'page_name'];
				}
				$location_url = $pageї'pageinfo_location'] . '.' . $phpEx;
				if($pageї'pageinfo_url_hook'] !== null || $pageї'pageinfo_url_add'] !== null)
				{
					$location_url .= '?';
					$add = '';

					if($pageї'pageinfo_url_add'] !== null)
						$add .= $pageї'pageinfo_url_add'];

					if($pageї'pageinfo_url_hook'] !== null)
						$add .= (!empty($add) ? '&' : '') . urlencode(constant($pageї'pageinfo_url_hook'])) . '=' . urlencode($rowї'session_page_data']);
					
					$location_url .= $add;
				}
			}
		}
		
		if(!$found)
		{
			$location = $langї'Forum_index'];
			$location_url = 'index.' . $phpEx;
			message_die(GENERAL_ERROR, 'Unhandled page: ' . $rowї'session_page'], '', __LINE__, __FILE__);
		}
similar changes were made to the admin script's online list as well. Basically what my pageinfo table does is allow slightly differing links and link text to appear in the user location. If you are considered an admin (mod's and admin's) you get a link to the exact topic someone is viewing, or posting a reply to. For "normal" users, they just see the forum (at most) the user is in.


note: this is in reference to phpBB 2.0.10, and that line numbers may vary wildly, as my version has been significantly altered.
note: I had to alter the code slightly for posting, so beware that the code may not fully run without some modification right off the bat.

Hail Feyd

Posted: Wed Oct 06, 2004 9:56 am
by neophyte
Thanks for the tutorial Feyd!

The cheap way to do it is to simply build a form that is directed at login.php. If you only want the forum to display if the person is logged out you can test for the presence of the right cookie...

Posted: Wed Oct 06, 2004 9:59 am
by feyd
true.. but if you want a lot tighter integration then I have quick simple access to their create_date function and other trinkets that would require writing a bunch of "custom"-ish code to load the data otherwise.. I've done it that way.. it was a major pain trying to hook into their login system (directly) and get the rest of the site to work correctly..

Posted: Wed Oct 06, 2004 10:14 am
by Draco_03
Feyd, great job!
I mean, man your a good programmer..
Kudos to you

I second that

Posted: Wed Oct 06, 2004 12:48 pm
by neophyte
Feyd, great job!
I mean, man your a good programmer..
Kudos to you
True;

Posted: Wed Oct 06, 2004 10:01 pm
by m3mn0n
Excellent.

feyd, you rule.