Addon Module Developer Docs
Addon modules allow you to create both admin pages and hooks to extend WHMCS further.
Modules can consist of just an admin page, or just hooks, or both. And they are all managed through the Setup > Addon Modules interface.
Once activated, the modules will display in a dedicated "Addons" dropdown menu within the admin area for quick & easy access from any page.
Management options consist of activating and deactivating of the modules, aswell as access control which allows full admins to define exactly which of the administrator roles are allowed to access each addon module.
We have a Video Tutorial demonstrating addon module management & access control @ http://www.whmcs.com/get-support/video-tutorials/#prettyPhoto/15/
Contents
Getting Started
To get started, you need to begin by choosing a name for your module. This name should be unique among all the modules in WHMCS, and should contain only letters & numbers, all lowercase. Underscores are on the only special characters that are accepted. For example, valid names would be:
mymodulename OR my_module_name OR my_module_v5
Once you have chosen your name, you need to create a directory and module file for it. The directory should be in the format /modules/addons/your_module_name/ and then the core module file within it should be named “your_module_name.php” to match the folder.
We have created an example module file which you can use as a basis for all your custom modules to help with getting started, and that can be found at the path /modules/addons/addonexample/ within your WHMCS installation. Now let’s move onto customising the module…
Configuration
The first step in the module is defining the configuration data. This includes the module name, version number, author, description and any configuration fields that might be needed. Below is an example of the config function function:
function demo_config() {
$configarray = array(
"name" => "Addon Example",
"description" => "This is a sample config function for an addon module",
"version" => "1.0",
"author" => "WHMCS",
"fields" => array(
"option1" => array ("FriendlyName" => "Option1", "Type" => "text", "Size" => "25",
"Description" => "Textbox", "Default" => "Example", ),
"option2" => array ("FriendlyName" => "Option2", "Type" => "password", "Size" => "25",
"Description" => "Password", ),
"option3" => array ("FriendlyName" => "Option3", "Type" => "yesno", "Size" => "25",
"Description" => "Sample Check Box", ),
"option4" => array ("FriendlyName" => "Option4", "Type" => "dropdown", "Options" =>
"1,2,3,4,5", "Description" => "Sample Dropdown", "Default" => "3", ),
"option5" => array ("FriendlyName" => "Option5", "Type" => "radio", "Options" =>
"Demo1,Demo2,Demo3", "Description" => "Radio Options Demo", ),
"option6" => array ("FriendlyName" => "Option6", "Type" => "textarea", "Rows" => "3",
"Cols" => "50", "Description" => "Description goes here", "Default" => "Test", ),
));
return $configarray;
}
The first 4 fields: name, version, author & description should all be fairly self-explanatory. These just need to contain the name you want displaying within the admin area for your module, version number, your name/company and a brief description of the addon.
The fields section is where you can define the input you need from end users to be able to make the module work. In this example we are asking for some API related information. Supported field types are “text”, “password”, “yesno” (checkboxes), “textarea”, “dropdown” and “radio”. If using the textarea option then you can add a “Rows” parameter to define the height of the box, and if using the dropdown type, then you must specify an “Options” parameter with a comma separated list of values.
There is an optional language variable you can also include if you will be using language files for your module - we’ll look at those in more detail later on.
Installation & Uninstallation
Modules can contain both activate and deactivate functions which run when an admin user activates or deactivates the module in the Addon Modules configuration area.
These functions can be used to create custom tables, database entries, perform license checks, or anything else you need to run at the time of initial activation or final deactivation. They can also be used to return messages, or errors to a user, so for example if you want to fail the activation or deactivation process due to a problem, or want to notify the user of a missing requirement or license issue.
The deactivation function should undo everything that the activation function does in order to fully remove the module from the users system.
One point to note is that there will already be an active database connection when the module is run, so to access the WHMCS database you won’t need to reconnect to the database.
So for example, the activate and deactivate functions could create and drop a table for use by the custom module as below:
function demo_activate() {
# Create Custom DB Table
$query = "CREATE TABLE `mod_addonexample` (`id` INT( 1 ) NOT NULL AUTO_INCREMENT ... ";
$result = mysql_query($query);
# Return Result
return array('status'=>'success','description'=>'This is an demo module only. In a real
module you might instruct a user how to get started with it here...');
return array('status'=>'error','description'=>'You can use the error status return to
indicate there was a problem activating the module');
return array('status'=>'info','description'=>'You can use the info status return to display
a message to the user');
}
function demo_deactivate() {
# Remove Custom DB Table
$query = "DROP TABLE `mod_addonexample`";
$result = mysql_query($query);
# Return Result
return array('status'=>'success','description'=>'If successful, you can return a message
to show the user here');
return array('status'=>'error','description'=>'If an error occurs you can return an error
message for display here');
return array('status'=>'info','description'=>'If you want to give an info message to a user
you can return it here');
}
Admin Area Content/Output
Output from the modules needs to be defined in the function your_module_name_output and should be actually output, (ie. echo’d) not returned. All output is captured by WHMCS and displayed within the admin interface template. The module name/title is automatically prefixed to the output.
Variables
The output function is passed all of the fields defined in your modules config, along with the values users have set for them, aswell as a “modulelink” variable which you can use to link back to the module.
Linking/Actions
Using the modulelink variable passed into the output function, you can then create links and forms that post back to your module. The modulelink will be in the format “addonmodules.php?module=xxxxxx” so for links you can then append “&var1=x&var2=y” or with forms you can use the POST form method to receive user input.
Within the output function you can then check the $_GET or $_POST variables received in the request in order to display other output or perform various tasks once links have been followed.
Admin User Data
You can access the currently logged in admin ID should you need that within your module using $_SESSION[‘adminid’] and from that can lookup any additional information you need in tbladmins.
Example
function demo_output($vars) {
$modulelink = $vars['modulelink'];
$version = $vars['version'];
$option1 = $vars['option1'];
$option2 = $vars['option2'];
$option3 = $vars['option3'];
$option4 = $vars['option4'];
$option5 = $vars['option5'];
$option6 = $vars['option6'];
$LANG = $vars['_lang'];
echo '<p>The date & time are currently '.date("Y-m-d H:i:s").'</p>';
}
Things aren't of course limited to just one file. For example within the _output function, because WHMCS simply wants you to output any content for the module, you can include other files, call templates, etc... The system is really flexible.
Client Area Output
Addon Modules also support generating client area output. This is done with the use of an _clientarea function within the module.
The functionality allows for modules to return output in the form of template files, stored within the module folder itself.
You can return a page title, breadcrumb path, and template variables to be defined. You can also require a client login with a simple true/false response. Language strings from the modules language file (see below) are also available to be used.
Client area modules are accessed using an URL in the format index.php?m=modulename
Here is a sample client area function demonstrating all of the available return variables:
function demo_clientarea($vars) {
$modulelink = $vars['modulelink'];
$version = $vars['version'];
$option1 = $vars['option1'];
$option2 = $vars['option2'];
$option3 = $vars['option3'];
$option4 = $vars['option4'];
$option5 = $vars['option5'];
$option6 = $vars['option6'];
$LANG = $vars['_lang'];
return array(
'pagetitle' => 'Addon Module',
'breadcrumb' => array('index.php?m=demo'=>'Demo Addon'),
'templatefile' => 'clienthome',
'requirelogin' => true, # or false
'vars' => array(
'testvar' => 'demo',
'anothervar' => 'value',
'sample' => 'test',
),
);
}
The above assumes a template by the name of clienthome.tpl existing within the module folder to be used for the output.
Multi-Language
Modules can be designed to support multiple languages should you wish.
For this, the addon module simply needs a lang subfolder creating within it, and within that language files can be created matching the names of the main WHMCS admin area language files located in the /admin/lang/ folder.
The language variables for custom modules are kept separate in language files within the module’s own folder to make installation and updating easier.
If language files exist, WHMCS will then automatically load these whenever the custom module is accessed, automatically selecting the appropriate language file based on the currently logged in administrators language profile setting. If no matching language file exists within the custom module’s folder for the language the admin is using then it will simply fall back to the default language you set in the module’s config array.
The language variables are then passed into both the _output and _sidebar functions variables array using “_lang”.
Please refer to the example addon modules language file located in /modules/addons/addonexample/lang/english.php for the format to use for your custom language variables.
Below is a demonstration of how you specify the default language for your module in the config array.
function demo_config() {
$configarray = array(
"name" => "Addon Example",
"description" => "This is a sample config function for an addon module",
"version" => "1.0",
"author" => "WHMCS",
"language" => "english",
"fields" => etc...
Hooks
To create hooks that your module should define within WHMCS, you simply need to create a file named “hooks.php” within your custom module folder, and that will then be automatically detected and any hooks loaded on every page of WHMCS.
The hook functions within that file should be defined in exactly the same way as normal.
Please refer to Hook Documentation for more info on creating and working with hooks in WHMCS.
Upgrades
Releasing updates and upgrades to your custom modules is likely something you will want to do at some point in time. And if those require modifying the database structure or performing other functions that would otherwise be performed in the _activate function when being activated for the first time, then you need some way of handling that.
With the Addon Modules system, this is a breeze with the upgrade function. The upgrade function is called the first time a module is accessed following an update. The update is detected by a change of version number in the _config array of the module, and so if a change is detected, the _upgrade function will be called. The upgrade function is passed the previous version number so that you can then decide what updates you need to run within that function to bring it up to date with your latest version.
An example of how this function can be used is demonstrated below:
function demo_upgrade($vars) {
$version = $vars['version'];
# Run SQL Updates for V1.0 to V1.1
if ($version < 1.1) {
$query = "ALTER `mod_addonexample` ADD `demo2` TEXT NOT NULL ";
$result = mysql_query($query);
}
# Run SQL Updates for V1.1 to V1.2
if ($version < 1.2) {
$query = "ALTER `mod_addonexample` ADD `demo3` TEXT NOT NULL ";
$result = mysql_query($query);
}
}