Custom action handling with SMF and SimpleSEF

After many people asking for the mod to support other types of mods, I’ve finally implemented the ability for mod authors to plug-in to SimpleSEF with their own custom URLs for their mods. It is simple and easy to do for any action in SMF (even stock actions, if you want to create custom URLs for those too).

First things first, create the file that will house your plug-in. The filename must follow this pattern: ssef_[your_action].php. The [your_action] should be changed to the name of the actual action in SMF. In my example, I am showing how to do the ‘profile’ action. I’ve named my file ssef_profile.php.

The next step is to create the contents of the file. The contents must be a PHP Class with the same name as the action, except with a capitalized first letter. See the class below for an example implementation.

[code lang=”php” smarttabs=”true” wraplines=”false”]<?php

/**
* Class to handle changing ?action=profile
*
* @author Matt Zuba
* @website http://www.mattzuba.com
* @action profile
* @mod Core
*/
class Profile
{
/**
* This function is passed an array of querystring parameters and turns them
* into a string to be used as the new URL. An example is presented in the
* function below. The passed in array looks something like:
* array(
* ‘sa’ => ‘mysubaction’,
* ‘board’ => ‘2.0’,
* ‘topic’ => ‘1.msg2′,
* );
* ‘action’ and ‘u’/’user’ are stripped from the URL passed in, you will need
* to handle everything else. Don’t forget to use sef_encode if any of the
* url parts will contain user-submitted data or data with odd characters.
*
* @param array Array of key=>value pairs parsed from the URL
* @return string Compiled string that represents the parameters passed in
*/
function create($url_params)
{
global $simpleSEF;

$sefstring2 = $sefstring3 = ”;
foreach ($url_params as $key => $value)
{
if ($value == ”)
$sefstring3 .= $key . ‘,/';
else
{
$sefstring2 .= $key;
if (is_array($value))
$sefstring2 .= ‘[‘ . key($value) . ‘],’ . $value[key($value)] . ‘/';
else
$sefstring2 .= ‘,’ . $value . ‘/';
}
}

$sefstring = ”;
if (isset($sefstring2))
$sefstring .= $sefstring2;
if (isset($sefstring3))
$sefstring .= $sefstring3;

return $sefstring;
}

/**
* This function is passed an array formed by splitting the URL by ‘/’.
* Using the array in the comments above, this array would like like:
* array(
* 0 => ‘sa,mysubaction’,
* 1 => ‘my_test_board’,
* 3 => ‘this_is_a_test_topic_1.msg2.html’,
* );
* Again, ‘action’ and ‘u’/’user’ are already parsed from the URL passed
* in, you will need to handle everything else. You need not worry about
* the # mark nor anything after it, it will be appended automatically.
*
* The returned array should resemble the array in the comment for create()
*
* @param array Array that represents all of the items passed in
* @return array An array of key=>value pairs
*/
function reverse($url_params)
{
global $simpleSEF;
$querystring = array();

foreach ($url_params as $part)
{
$temp = array();
if (strpos($part, ‘,’) !== false)
$part = substr_replace($part, ‘=’, strpos($part, ‘,’), 1);
parse_str($part, $temp);
$querystring += $temp;
}

return $querystring;
}
}[/code]

The best way to allow users to install these is via SMF’s package manager. Below is a sample package-info.xml file that can be used. If you choose to create your own, or include it with your own mod install, you must at least have the code to invalidate the ssef_extension cache (see the <code> tag in the sample below). The directory to place the extension into should be $sourcedir/SimpleSEF-Ext.

[code lang=”xml” smarttabs=”true” wraplines=”false”]<?xml version="1.0"?>
<!DOCTYPE package-info SYSTEM "http://www.simplemachines.org/xml/package-info">

<package-info xmlns="http://www.simplemachines.org/xml/package-info" xmlns:smf="http://www.simplemachines.org/">
<id>slammeddime:ssef_profile</id>
<name>SimpleSEF Profile Extension</name>
<version>1.0</version>
<type>modification</type>

<install for="2.0 RC4">
<readme parsebbc="true">readme.txt</readme>
<code type="inline"><![CDATA[<?php cache_put_data(‘ssef_extensions’, NULL, 3600);]]></code>
<require-file name="ssef_profile.php" destination="$sourcedir/SimpleSEF-Ext" />
</install>

<uninstall for="2.0 RC4">
<code type="inline"><![CDATA[<?php cache_put_data(‘ssef_extensions’, NULL, 3600);]]></code>
<remove-file name="$sourcedir/SimpleSEF-Ext/ssef_profile.php" />
</uninstall>
</package-info>
[/code]

Now you just need to package it up into a .zip or .tar.gz file and users can easily install this into their SMF install while using SimpleSEF.

Keep in mind that you should NOT build your code around this mod. You should already have a functional mod before attempting to create your own custom URL handler.