Integrating Invision Power Board (back) into

Notes on how the project integrating with Invision Power Board went and how it was done.

As I’ve mentioned in the past, has something of an odd history.

It was originally a part of DetroitHockey.Net, which at that time used Invision Power Board as a forum system.  When I spun FHS off into its own site, I migrated user management and messaging to a system built around a Slack team.  That served us well for several years but it became apparent that it had flaws, one of which being difficulty scaling up.  As such, I made the decision to bring Invision Power Board back in, running it alongside the Slack team.

IPB gave me user management out of the box, so I removed much of my custom-built functionality around that.

I was able to add our Slack team as an OAuth-based login method for IPB, so existing members could continue logging in with their Slack credentials and all of the other Slack integrations in the site could key off of that information.

To allow users to log in and out using the forum functionality but return to a non-forum page from which they came, two changes to IPB code were required in their login class, /community/applications/core/modules/front/system/login.php.

On lines 59-61,  we force their referrer check to accept external URLs.

if ( \IPS\Request::i()->referrer( TRUE, TRUE ) ) {
	$ref = \IPS\Request::i()->referrer( TRUE, TRUE );

Then at line 259, we check whether not a referrer was defined and, is so, use it.

$ref = \IPS\Request::i()->ref;

/* Work out where we will be going after log out */
if( !empty( $ref ) ) {
	$referrer = \IPS\Http\Url::createFromString( @base64_decode( $ref ) );
	$redirectUrl = $referrer ?: \IPS\Http\Url::internal( '' );
} elseif( !empty( $_SERVER['HTTP_REFERER'] ) )

To determine whether or not a member is logged in in non-forum areas of FHS, we tap into IPB’s session management and use it to populate our own.  It’s a little messy, especially as IPB’s code is not meant to be included into a non-IPB codebase.  We end up having to do some cleanup but it looks something like this:

First we pull in the session details.

require_once $community_path . 'init.php';

$session_id = \IPS\Request::i()->cookie['IPSSessionFront'] ?? \IPS\Session::i()->id;

If we need to, we can get the member ID.

$member_id = \IPS\Member::loggedIn()->member_id;

Then we revert as many of the changes IPB made as possible.

define( 'IN_IPB', FALSE );

That gives us an IPB installation acting as single-sign on for the site.

Other points of integration are driven primarily by the IPB API.  On league creation, a forum and calendar are created for the league, with the IDs of each stored in the league config so that messages can automatically be posted there later.

I also added tooling that allows for cross-posting between the forums and Slack.  As the expectation is that some leagues will continue to use Slack while most use the forums, the idea is for no messages to get lost between the two.  This might lead to over-communication but I would rather see that than the opposite.