Integration hooks

A SMF integration hook is a single line of code that calls one or more functions from a list stored in $modSettings. This means that a modder can cause some new code to be run at that point, without changing the core code. It means modders need not worry that some other mod might already have altered the code they want to change. The introduction of integration hooks to SMF has the potential to radically simplify the task of creating and installing many types of mods, and creating bridges to third-party code. Integration hooks are only available in SMF version 2.0 and onwards! A mod's installation package can permanently store its list of hook functions on the database, and specify files to load. A mod can also add integration hook functions from within its code.

Using Integration Hooks
Integration Hooks might seem subtle and mysterious, because it makes the code more dynamic. Anyone reading through the code will have to know the contents of $modSettings in order to know what code is going to be executed at a hook. The concept is simple, though. Just as $modSettings has been used to store all kinds of settings, it is now being used to store the names of functions to execute when an integration hook is called. Most integration hooks appear in the code as a call to call_integration_hook. function call_integration_hook('name', array(&$param1, &$param2)); Where 'name' is the name of the integration hook, as given in the list below, and the array contains all the parameters to be passed to any integration hook functions that may have been added to the named hook. Because these parameters are passed with the &$ syntax, the parameters are available to be modified by the integration hook functions. In order to take advantage of this, the function definitions must also use the &$ syntax for receiving the parameters function my_integration_hook_function(&$param1, &$param2){.....} Before calling each integration hook function, call_integration_hook will check whether that function is callable. If not, it will silently skip that function.

The same function can be added to multiple hooks, but cannot be added more than once to the same hook. It is important to choose unique function names, perhaps by using the Mod name (or an abbreviation) as a prefix, in order to decrease the likelihood that some other mod writer will someday create a function of the same name.

Only one of the integration hooks is not implemented with call_integration_hook. This is the hook 'integrate_pre_load'. This hook simply includes all the files that have been added to the hook.

One of the first mods to take advantage of integration hooks, SlammedDime's SimpleSEF mod, makes only a few edits to the core code, simply to add admin options. The rest of the work is done using integration hooks to load the main SimpleSEF file.

Mod writers would generally do this in an installation script that runs during mod install - like SimpleSEF does. To avoid overwriting any settings already there, use add_integration_function. If it's a one-off thing, use phpMyAdmin and add a new row to, or modify an existing row in the {db_prefix}settings table.

The hook 'integrate_pre_load' is designed to pre-load files containing integration hook function definitions. By adding your file to this hook at install time, you can ensure that all your integration hook functions will be loaded on every page of the forum.

add_integration_function
add_integration_function ($hook_name, $hook_executes, $make_permanent); Depending on the $hook_name used, the value of  should be either   or a. If $make_permanent is TRUE, the change is saved on the database and the $modSettings cache (if caching is used). If $make_permanent is FALSE, no changes are made to the database or the cache.

A modwriter working on a mod called SimplyPerfect might add something like the following to the mod's install.php file: add_integration_function('integrate_pre_include', '$sourcedir/Subs-SimplyPerfect.php',TRUE); add_integration_function('integrate_actions','SimplyPerfect_actions',TRUE); add_integration_function('integrate_bbc_codes','SimplyPerfect_bbc_codes',TRUE);

remove_integration_function
remove_integration_function($hook_name, $function_name); This function removes an integration hook (temporary or permanent) from $modSettings, from the database, and from the $modSettings cache.

A mod which needs to temporarily add some novel BBC codes on a special page could use: add_integration_function('integrate_bbc_codes','SimplyTemporary_bbc_codes',FALSE); ... remove_integration_function('integrate_bbc_codes','SimplyTemporary_bbc_codes');

List of Integration Hooks
So, what are the hooks and how do you use them?

This list documents each of the hooks, what it does, and what it expects as input.

Each hook can be defined and set using the names below. e.g. integrate_pre_include would be referenced in $modSettings as $modSettings['integrate_pre_include'], and managed in the settings table under that name too.

Each integration hook has been described in the following manner:

* Called from: - lists which file it's called from, and at what point the hook will be called on your behalf.

* Purpose: - what the hook is designed for and what it can allow you to do.

* Accepts: - what type of input the hook is expecting. In almost every case this will simply be the name of a function to call, though can be a static method of a class. It should be obvious that the function will need to already be loaded and thus available to SMF already - if not, you may need to ensure integrate_pre_include loads it, the main SMF files contain it, or you otherwise ensure it is loaded.

* Sends: - the list of parameters in order that the hook will be sent from SMF. May be no variables, may be many. If the hook sends variables that you may want to modify before your function ends, make sure your function states it wants the variables by reference.

For example if a hook states that it sends $value1, $value2 and you want to be able to modify those in your function myfunc, the specification would be: function myfunc(&$value1, &$value2)

integrate_validate_login
Unlike other functions, this hook explicitly requires a return value - not all other hook functions handle return values. The return value is a string - either "retry" if there was an issue and user needs to try again, or anything else if the hooked function does not have an issue with the supplied details.

integrate_verify_password
Unlike other functions, this hook explicitly requires a return value - not all other hook functions handle return values. The return value is either exactly identical to true if acceptable, or anything else is a fail.

integrate_verify_user
Unlike other functions, this hook explicitly requires a return value - few other hook functions handle return values. The return value is cast to an integer to represent user id; 0 = not logged in and to refer to cookie then session, otherwise it represents the user id.

integrate_change_member_data
NOTE: Not all values are exported through this hook. Only the following will be exported - any other values updated will not.
 * 'member_name' - user name
 * 'real_name' - display name
 * 'email_address' - email address
 * 'id_group' - primary user group (only)
 * 'gender' - male/female
 * 'birthdate' - date of birth
 * 'website_title' - name of website specified in profile
 * 'website_url' - address of website specified in profile
 * 'location' - the location stated in profile
 * 'hide_email' - whether the user's email address should be considered private (admin visible only)
 * 'time_format' - the user's time format string for their own time format
 * 'time_offset' - the user's own time offset (from profile)
 * 'avatar' - gallery or URL specified avatar
 * 'lngfile' - user's language

integrate_buffer
Unlike other functions, this hook explicitly requires a return value - not all other hook functions handle return values. The return value is the buffer contents.

integrate_magic_quotes
This one isn't actually a function, it's a setting that's relevant. PHP's idea of magic quoting is one of the most irritating ideas it has ever had, to attempt to automatically be able to quote values that are incoming from userland. Unfortunately its behavior is somewhat unpredictable and therefore unreliable.

In the process of sanitizing $_GET, SMF does its own clean-up of magic quotes, handling the various types that may be incoming, but other systems do not do this and rely on default PHP behavior. This setting overrides SMF's behavior and returns it to the default.