Current status
This commit is contained in:
parent
5be7ff722b
commit
0a435d2ae3
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2017 WHMCS, Limited
|
Copyright (c) 2017 WHMCS, Limited, 2023 Kumi Systems e.U.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
43
README.md
43
README.md
|
@ -1,32 +1,14 @@
|
||||||
# WHMCS Sample Addon Module #
|
# Account Selection Module for WHMCS
|
||||||
|
|
||||||
## Summary ##
|
## Summary
|
||||||
|
|
||||||
An addon module allows you to add additional functionality to WHMCS. It
|
This module allows you to select the account that you want a specific invoice item to be assigned to in accounting.
|
||||||
can provide both client and admin facing user interfaces, as well as
|
|
||||||
utilise hook functionality within WHMCS.
|
|
||||||
|
|
||||||
This sample file demonstrates how an addon module for WHMCS should be
|
This was a specific requirement for a client, but the concept of displaying a dynamic list of values for a custom invoice item field may be useful to others.
|
||||||
structured and exercises all supported functionality.
|
|
||||||
|
|
||||||
For more information, please refer to the online documentation at
|
This addon is a fork of the [WHMCS Sample Addon Module](https://github.com/WHMCS/sample-addon-module) and, as such, is licensed under the MIT License.
|
||||||
https://developers.whmcs.com/addon-modules/
|
|
||||||
|
|
||||||
## Recommended Module Content ##
|
## Minimum Requirements
|
||||||
|
|
||||||
The recommended structure of an addon module is as follows.
|
|
||||||
|
|
||||||
```
|
|
||||||
addonmodule/
|
|
||||||
|- lang/
|
|
||||||
|- lib/
|
|
||||||
|- templates/
|
|
||||||
| addonmodule.php
|
|
||||||
| hooks.php
|
|
||||||
| logo.png
|
|
||||||
```
|
|
||||||
|
|
||||||
## Minimum Requirements ##
|
|
||||||
|
|
||||||
For the latest WHMCS minimum system requirements, please refer to
|
For the latest WHMCS minimum system requirements, please refer to
|
||||||
http://docs.whmcs.com/System_Requirements
|
http://docs.whmcs.com/System_Requirements
|
||||||
|
@ -34,14 +16,7 @@ http://docs.whmcs.com/System_Requirements
|
||||||
We recommend your module follows the same minimum requirements wherever
|
We recommend your module follows the same minimum requirements wherever
|
||||||
possible.
|
possible.
|
||||||
|
|
||||||
## Tests ##
|
## License
|
||||||
|
|
||||||
We strongly encourage you to write unit tests for your work. Within this SDK we
|
This module is licensed under the MIT License. Please see the LICENSE file for
|
||||||
provide a sample unit test based upon the widely used PHPUnit.
|
more information.
|
||||||
|
|
||||||
## Useful Resources
|
|
||||||
* [Developer Portal](https://developers.whmcs.com/)
|
|
||||||
* [Hook Documentation](https://developers.whmcs.com/hooks/)
|
|
||||||
* [API Documentation](https://developers.whmcs.com/api/)
|
|
||||||
|
|
||||||
[WHMCS Limited](https://www.whmcs.com)
|
|
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"name": "whmcs/sample-addon-module",
|
|
||||||
"description": "Sample Addon Module for WHMCS Billing Automation Platform",
|
|
||||||
"keywords": [
|
|
||||||
"whmcs",
|
|
||||||
"web host automation platform",
|
|
||||||
"addon module"
|
|
||||||
],
|
|
||||||
"homepage": "http://www.whmcs.com/",
|
|
||||||
"license": "MIT",
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "WHMCS Development Team",
|
|
||||||
"email": "development@whmcs.com",
|
|
||||||
"homepage": "http://www.whmcs.com/",
|
|
||||||
"role": "Developer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"support": {
|
|
||||||
"email": "support@whmcs.com",
|
|
||||||
"forum": "http://forums.whmcs.com/",
|
|
||||||
"wiki": "http://docs.whmcs.com/"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "@stable"
|
|
||||||
}
|
|
||||||
}
|
|
152
modules/addons/accounting/accounting.php
Normal file
152
modules/addons/accounting/accounting.php
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* WHMCS Account Selector Addon Module
|
||||||
|
*
|
||||||
|
* An addon module for WHMCS that allows you to select the account to be used
|
||||||
|
* for a given invoice item in accounting.
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) WHMCS Limited 2017, 2023 Kumi Systems e.U.
|
||||||
|
* @license MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
use WHMCS\Database\Capsule;
|
||||||
|
use WHMCS\Module\Addon\AddonModule\Admin\AdminDispatcher;
|
||||||
|
|
||||||
|
if (!defined("WHMCS")) {
|
||||||
|
die("This file cannot be accessed directly");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define addon module configuration parameters.
|
||||||
|
*
|
||||||
|
* Includes a number of required system fields including name, description,
|
||||||
|
* author, language and version.
|
||||||
|
*
|
||||||
|
* Also allows you to define any configuration parameters that should be
|
||||||
|
* presented to the user when activating and configuring the module. These
|
||||||
|
* values are then made available in all module function calls.
|
||||||
|
*
|
||||||
|
* Examples of each and their possible configuration parameters are provided in
|
||||||
|
* the fields parameter below.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function accounting_config()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// Display name for your module
|
||||||
|
'name' => 'Account Selector',
|
||||||
|
// Description displayed within the admin interface
|
||||||
|
'description' => 'This module allows you to select the account to be used for a given invoice item in accounting.',
|
||||||
|
// Module author name
|
||||||
|
'author' => 'Kumi Systems e.U.',
|
||||||
|
// Default language
|
||||||
|
'language' => 'english',
|
||||||
|
// Version number
|
||||||
|
'version' => '1.0',
|
||||||
|
'fields' => [
|
||||||
|
'Available Accounts' => [
|
||||||
|
'FriendlyName' => 'Available Accounts',
|
||||||
|
'Type' => 'textarea',
|
||||||
|
'Rows' => '20',
|
||||||
|
'Cols' => '100',
|
||||||
|
'Default' => '1234 - Example Account',
|
||||||
|
'Description' => 'List of available accounts, one per line. Format: Account Number - Account Name',
|
||||||
|
],
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called upon activation of the module for the first time.
|
||||||
|
* Used to create database tables required by the module.
|
||||||
|
*
|
||||||
|
* @see https://developers.whmcs.com/advanced/db-interaction/
|
||||||
|
*
|
||||||
|
* @return array Optional success/failure message
|
||||||
|
*/
|
||||||
|
function accounting_activate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Capsule::schema()
|
||||||
|
->create(
|
||||||
|
'mod_accounting',
|
||||||
|
function ($table) {
|
||||||
|
/** @var \Illuminate\Database\Schema\Blueprint $table */
|
||||||
|
$table->increments('id');
|
||||||
|
$table->integer('invoice');
|
||||||
|
$table->integer('item');
|
||||||
|
$table->text('account');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'status' => 'success',
|
||||||
|
'description' => 'Successfully created mod_accounting table. Now, please set up your accounts in the module configuration.',
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return [
|
||||||
|
'status' => "error",
|
||||||
|
'description' => 'Unable to create mod_accounting: ' . $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate.
|
||||||
|
*
|
||||||
|
* Called upon deactivation of the module.
|
||||||
|
* Used to drop database tables created by the module.
|
||||||
|
*
|
||||||
|
* @return array Optional success/failure message
|
||||||
|
*/
|
||||||
|
function accounting_deactivate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Capsule::schema()
|
||||||
|
->dropIfExists('mod_accounting');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'status' => 'success',
|
||||||
|
'description' => 'Dropped mod_accounting table.',
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return [
|
||||||
|
// Supported values here include: success, error or info
|
||||||
|
"status" => "error",
|
||||||
|
"description" => "Unable to drop mod_accounting: {$e->getMessage()}",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin Area Output.
|
||||||
|
*
|
||||||
|
* Called when the addon module is accessed via the admin area.
|
||||||
|
* Should return HTML output for display to the admin user.
|
||||||
|
*
|
||||||
|
* This function is optional.
|
||||||
|
*
|
||||||
|
* @see AddonModule\Admin\Controller::index()
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function accounting_output($vars)
|
||||||
|
{
|
||||||
|
// Get common module parameters
|
||||||
|
$modulelink = $vars['modulelink'];
|
||||||
|
$version = $vars['version'];
|
||||||
|
$_lang = $vars['_lang']; // an array of the currently loaded language variables
|
||||||
|
|
||||||
|
// Get module configuration parameters
|
||||||
|
$configTextareaField = $vars['Available Accounts'];
|
||||||
|
|
||||||
|
// Dispatch and handle request here. What follows is a demonstration of one
|
||||||
|
// possible way of handling this using a very basic dispatcher implementation.
|
||||||
|
|
||||||
|
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
||||||
|
|
||||||
|
$dispatcher = new AdminDispatcher();
|
||||||
|
$response = $dispatcher->dispatch($action, $vars);
|
||||||
|
echo $response;
|
||||||
|
}
|
56
modules/addons/accounting/hooks.php
Normal file
56
modules/addons/accounting/hooks.php
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* WHMCS SDK Sample Addon Module Hooks File
|
||||||
|
*
|
||||||
|
* Hooks allow you to tie into events that occur within the WHMCS application.
|
||||||
|
*
|
||||||
|
* This allows you to execute your own code in addition to, or sometimes even
|
||||||
|
* instead of that which WHMCS executes by default.
|
||||||
|
*
|
||||||
|
* @see https://developers.whmcs.com/hooks/
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) WHMCS Limited 2017
|
||||||
|
* @license http://www.whmcs.com/license/ WHMCS Eula
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A hook displaying a drop-down field for selection of an account to the left of each invoice item in the invoice edit page.
|
||||||
|
|
||||||
|
use WHMCS\Database\Capsule;
|
||||||
|
|
||||||
|
add_hook('InvoiceEdit', 1, function(array $params) {
|
||||||
|
try {
|
||||||
|
// Get the invoice ID from the parameters.
|
||||||
|
$invoiceId = $params['invoiceid'];
|
||||||
|
// Get the invoice items from the database.
|
||||||
|
$invoiceItems = Capsule::table('tblinvoiceitems')
|
||||||
|
->where('invoiceid', $invoiceId)
|
||||||
|
->get();
|
||||||
|
// Get the available accounts from the module configuration.
|
||||||
|
$availableAccounts = explode("\n", $params['Available Accounts']);
|
||||||
|
// Create the drop-down field for each invoice item.
|
||||||
|
foreach ($invoiceItems as $invoiceItem) {
|
||||||
|
$accountSelector = '<select name="accountSelector[' . $invoiceItem->id . ']">';
|
||||||
|
foreach ($availableAccounts as $availableAccount) {
|
||||||
|
$accountSelector .= '<option value="' . $availableAccount . '">' . $availableAccount . '</option>';
|
||||||
|
}
|
||||||
|
$accountSelector .= '</select>';
|
||||||
|
// Add the drop-down field to the invoice item.
|
||||||
|
echo '<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("input[name=\'description[' . $invoiceItem->id . ']\']").before("' . $accountSelector . '");
|
||||||
|
});
|
||||||
|
</script>';
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Consider logging or reporting the error.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
add_hook('ClientEdit', 1, function(array $params) {
|
||||||
|
try {
|
||||||
|
// Call the service's function, using the values provided by WHMCS in
|
||||||
|
// `$params`.
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Consider logging or reporting the error.
|
||||||
|
}
|
||||||
|
});
|
|
@ -22,12 +22,7 @@ class Controller {
|
||||||
$LANG = $vars['_lang']; // an array of the currently loaded language variables
|
$LANG = $vars['_lang']; // an array of the currently loaded language variables
|
||||||
|
|
||||||
// Get module configuration parameters
|
// Get module configuration parameters
|
||||||
$configTextField = $vars['Text Field Name'];
|
$configTextareaField = $vars['Available Accounts'];
|
||||||
$configPasswordField = $vars['Password Field Name'];
|
|
||||||
$configCheckboxField = $vars['Checkbox Field Name'];
|
|
||||||
$configDropdownField = $vars['Dropdown Field Name'];
|
|
||||||
$configRadioField = $vars['Radio Field Name'];
|
|
||||||
$configTextareaField = $vars['Textarea Field Name'];
|
|
||||||
|
|
||||||
return <<<EOF
|
return <<<EOF
|
||||||
|
|
||||||
|
@ -40,11 +35,6 @@ class Controller {
|
||||||
<p>Values of the configuration field are as follows:</p>
|
<p>Values of the configuration field are as follows:</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
Text Field: {$configTextField}<br>
|
|
||||||
Password Field: {$configPasswordField}<br>
|
|
||||||
Checkbox Field: {$configCheckboxField}<br>
|
|
||||||
Dropdown Field: {$configDropdownField}<br>
|
|
||||||
Radio Field: {$configRadioField}<br>
|
|
||||||
Textarea Field: {$configTextareaField}
|
Textarea Field: {$configTextareaField}
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -77,12 +67,7 @@ EOF;
|
||||||
$LANG = $vars['_lang']; // an array of the currently loaded language variables
|
$LANG = $vars['_lang']; // an array of the currently loaded language variables
|
||||||
|
|
||||||
// Get module configuration parameters
|
// Get module configuration parameters
|
||||||
$configTextField = $vars['Text Field Name'];
|
$configTextareaField = $vars['Available Accounts'];
|
||||||
$configPasswordField = $vars['Password Field Name'];
|
|
||||||
$configCheckboxField = $vars['Checkbox Field Name'];
|
|
||||||
$configDropdownField = $vars['Dropdown Field Name'];
|
|
||||||
$configRadioField = $vars['Radio Field Name'];
|
|
||||||
$configTextareaField = $vars['Textarea Field Name'];
|
|
||||||
|
|
||||||
return <<<EOF
|
return <<<EOF
|
||||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -1,344 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* WHMCS SDK Sample Addon Module
|
|
||||||
*
|
|
||||||
* An addon module allows you to add additional functionality to WHMCS. It
|
|
||||||
* can provide both client and admin facing user interfaces, as well as
|
|
||||||
* utilise hook functionality within WHMCS.
|
|
||||||
*
|
|
||||||
* This sample file demonstrates how an addon module for WHMCS should be
|
|
||||||
* structured and exercises all supported functionality.
|
|
||||||
*
|
|
||||||
* Addon Modules are stored in the /modules/addons/ directory. The module
|
|
||||||
* name you choose must be unique, and should be all lowercase, containing
|
|
||||||
* only letters & numbers, always starting with a letter.
|
|
||||||
*
|
|
||||||
* Within the module itself, all functions must be prefixed with the module
|
|
||||||
* filename, followed by an underscore, and then the function name. For this
|
|
||||||
* example file, the filename is "addonmodule" and therefore all functions
|
|
||||||
* begin "addonmodule_".
|
|
||||||
*
|
|
||||||
* For more information, please refer to the online documentation.
|
|
||||||
*
|
|
||||||
* @see https://developers.whmcs.com/addon-modules/
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) WHMCS Limited 2017
|
|
||||||
* @license http://www.whmcs.com/license/ WHMCS Eula
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Require any libraries needed for the module to function.
|
|
||||||
* require_once __DIR__ . '/path/to/library/loader.php';
|
|
||||||
*
|
|
||||||
* Also, perform any initialization required by the service's library.
|
|
||||||
*/
|
|
||||||
|
|
||||||
use WHMCS\Database\Capsule;
|
|
||||||
use WHMCS\Module\Addon\AddonModule\Admin\AdminDispatcher;
|
|
||||||
use WHMCS\Module\Addon\AddonModule\Client\ClientDispatcher;
|
|
||||||
|
|
||||||
if (!defined("WHMCS")) {
|
|
||||||
die("This file cannot be accessed directly");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define addon module configuration parameters.
|
|
||||||
*
|
|
||||||
* Includes a number of required system fields including name, description,
|
|
||||||
* author, language and version.
|
|
||||||
*
|
|
||||||
* Also allows you to define any configuration parameters that should be
|
|
||||||
* presented to the user when activating and configuring the module. These
|
|
||||||
* values are then made available in all module function calls.
|
|
||||||
*
|
|
||||||
* Examples of each and their possible configuration parameters are provided in
|
|
||||||
* the fields parameter below.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function addonmodule_config()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
// Display name for your module
|
|
||||||
'name' => 'Addon Module Sample',
|
|
||||||
// Description displayed within the admin interface
|
|
||||||
'description' => 'This module provides an example WHMCS Addon Module'
|
|
||||||
. ' which can be used as a basis for building a custom addon module.',
|
|
||||||
// Module author name
|
|
||||||
'author' => 'Your name goes here',
|
|
||||||
// Default language
|
|
||||||
'language' => 'english',
|
|
||||||
// Version number
|
|
||||||
'version' => '1.0',
|
|
||||||
'fields' => [
|
|
||||||
// a text field type allows for single line text input
|
|
||||||
'Text Field Name' => [
|
|
||||||
'FriendlyName' => 'Text Field Name',
|
|
||||||
'Type' => 'text',
|
|
||||||
'Size' => '25',
|
|
||||||
'Default' => 'Default value',
|
|
||||||
'Description' => 'Description goes here',
|
|
||||||
],
|
|
||||||
// a password field type allows for masked text input
|
|
||||||
'Password Field Name' => [
|
|
||||||
'FriendlyName' => 'Password Field Name',
|
|
||||||
'Type' => 'password',
|
|
||||||
'Size' => '25',
|
|
||||||
'Default' => '',
|
|
||||||
'Description' => 'Enter secret value here',
|
|
||||||
],
|
|
||||||
// the yesno field type displays a single checkbox option
|
|
||||||
'Checkbox Field Name' => [
|
|
||||||
'FriendlyName' => 'Checkbox Field Name',
|
|
||||||
'Type' => 'yesno',
|
|
||||||
'Description' => 'Tick to enable',
|
|
||||||
],
|
|
||||||
// the dropdown field type renders a select menu of options
|
|
||||||
'Dropdown Field Name' => [
|
|
||||||
'FriendlyName' => 'Dropdown Field Name',
|
|
||||||
'Type' => 'dropdown',
|
|
||||||
'Options' => [
|
|
||||||
'option1' => 'Display Value 1',
|
|
||||||
'option2' => 'Second Option',
|
|
||||||
'option3' => 'Another Option',
|
|
||||||
],
|
|
||||||
'Default' => 'option2',
|
|
||||||
'Description' => 'Choose one',
|
|
||||||
],
|
|
||||||
// the radio field type displays a series of radio button options
|
|
||||||
'Radio Field Name' => [
|
|
||||||
'FriendlyName' => 'Radio Field Name',
|
|
||||||
'Type' => 'radio',
|
|
||||||
'Options' => 'First Option,Second Option,Third Option',
|
|
||||||
'Default' => 'Third Option',
|
|
||||||
'Description' => 'Choose your option!',
|
|
||||||
],
|
|
||||||
// the textarea field type allows for multi-line text input
|
|
||||||
'Textarea Field Name' => [
|
|
||||||
'FriendlyName' => 'Textarea Field Name',
|
|
||||||
'Type' => 'textarea',
|
|
||||||
'Rows' => '3',
|
|
||||||
'Cols' => '60',
|
|
||||||
'Default' => 'A default value goes here...',
|
|
||||||
'Description' => 'Freeform multi-line text input field',
|
|
||||||
],
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activate.
|
|
||||||
*
|
|
||||||
* Called upon activation of the module for the first time.
|
|
||||||
* Use this function to perform any database and schema modifications
|
|
||||||
* required by your module.
|
|
||||||
*
|
|
||||||
* This function is optional.
|
|
||||||
*
|
|
||||||
* @see https://developers.whmcs.com/advanced/db-interaction/
|
|
||||||
*
|
|
||||||
* @return array Optional success/failure message
|
|
||||||
*/
|
|
||||||
function addonmodule_activate()
|
|
||||||
{
|
|
||||||
// Create custom tables and schema required by your module
|
|
||||||
try {
|
|
||||||
Capsule::schema()
|
|
||||||
->create(
|
|
||||||
'mod_addonexample',
|
|
||||||
function ($table) {
|
|
||||||
/** @var \Illuminate\Database\Schema\Blueprint $table */
|
|
||||||
$table->increments('id');
|
|
||||||
$table->text('demo');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return [
|
|
||||||
// Supported values here include: success, error or info
|
|
||||||
'status' => 'success',
|
|
||||||
'description' => 'This is a demo module only. '
|
|
||||||
. 'In a real module you might report a success or instruct a '
|
|
||||||
. 'user how to get started with it here.',
|
|
||||||
];
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return [
|
|
||||||
// Supported values here include: success, error or info
|
|
||||||
'status' => "error",
|
|
||||||
'description' => 'Unable to create mod_addonexample: ' . $e->getMessage(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deactivate.
|
|
||||||
*
|
|
||||||
* Called upon deactivation of the module.
|
|
||||||
* Use this function to undo any database and schema modifications
|
|
||||||
* performed by your module.
|
|
||||||
*
|
|
||||||
* This function is optional.
|
|
||||||
*
|
|
||||||
* @see https://developers.whmcs.com/advanced/db-interaction/
|
|
||||||
*
|
|
||||||
* @return array Optional success/failure message
|
|
||||||
*/
|
|
||||||
function addonmodule_deactivate()
|
|
||||||
{
|
|
||||||
// Undo any database and schema modifications made by your module here
|
|
||||||
try {
|
|
||||||
Capsule::schema()
|
|
||||||
->dropIfExists('mod_addonexample');
|
|
||||||
|
|
||||||
return [
|
|
||||||
// Supported values here include: success, error or info
|
|
||||||
'status' => 'success',
|
|
||||||
'description' => 'This is a demo module only. '
|
|
||||||
. 'In a real module you might report a success here.',
|
|
||||||
];
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return [
|
|
||||||
// Supported values here include: success, error or info
|
|
||||||
"status" => "error",
|
|
||||||
"description" => "Unable to drop mod_addonexample: {$e->getMessage()}",
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upgrade.
|
|
||||||
*
|
|
||||||
* Called the first time the module is accessed following an update.
|
|
||||||
* Use this function to perform any required database and schema modifications.
|
|
||||||
*
|
|
||||||
* This function is optional.
|
|
||||||
*
|
|
||||||
* @see https://laravel.com/docs/5.2/migrations
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function addonmodule_upgrade($vars)
|
|
||||||
{
|
|
||||||
$currentlyInstalledVersion = $vars['version'];
|
|
||||||
|
|
||||||
/// Perform SQL schema changes required by the upgrade to version 1.1 of your module
|
|
||||||
if ($currentlyInstalledVersion < 1.1) {
|
|
||||||
$schema = Capsule::schema();
|
|
||||||
// Alter the table and add a new text column called "demo2"
|
|
||||||
$schema->table('mod_addonexample', function($table) {
|
|
||||||
$table->text('demo2');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Perform SQL schema changes required by the upgrade to version 1.2 of your module
|
|
||||||
if ($currentlyInstalledVersion < 1.2) {
|
|
||||||
$schema = Capsule::schema();
|
|
||||||
// Alter the table and add a new text column called "demo3"
|
|
||||||
$schema->table('mod_addonexample', function($table) {
|
|
||||||
$table->text('demo3');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Admin Area Output.
|
|
||||||
*
|
|
||||||
* Called when the addon module is accessed via the admin area.
|
|
||||||
* Should return HTML output for display to the admin user.
|
|
||||||
*
|
|
||||||
* This function is optional.
|
|
||||||
*
|
|
||||||
* @see AddonModule\Admin\Controller::index()
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function addonmodule_output($vars)
|
|
||||||
{
|
|
||||||
// Get common module parameters
|
|
||||||
$modulelink = $vars['modulelink']; // eg. addonmodules.php?module=addonmodule
|
|
||||||
$version = $vars['version']; // eg. 1.0
|
|
||||||
$_lang = $vars['_lang']; // an array of the currently loaded language variables
|
|
||||||
|
|
||||||
// Get module configuration parameters
|
|
||||||
$configTextField = $vars['Text Field Name'];
|
|
||||||
$configPasswordField = $vars['Password Field Name'];
|
|
||||||
$configCheckboxField = $vars['Checkbox Field Name'];
|
|
||||||
$configDropdownField = $vars['Dropdown Field Name'];
|
|
||||||
$configRadioField = $vars['Radio Field Name'];
|
|
||||||
$configTextareaField = $vars['Textarea Field Name'];
|
|
||||||
|
|
||||||
// Dispatch and handle request here. What follows is a demonstration of one
|
|
||||||
// possible way of handling this using a very basic dispatcher implementation.
|
|
||||||
|
|
||||||
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
|
||||||
|
|
||||||
$dispatcher = new AdminDispatcher();
|
|
||||||
$response = $dispatcher->dispatch($action, $vars);
|
|
||||||
echo $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Admin Area Sidebar Output.
|
|
||||||
*
|
|
||||||
* Used to render output in the admin area sidebar.
|
|
||||||
* This function is optional.
|
|
||||||
*
|
|
||||||
* @param array $vars
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function addonmodule_sidebar($vars)
|
|
||||||
{
|
|
||||||
// Get common module parameters
|
|
||||||
$modulelink = $vars['modulelink'];
|
|
||||||
$version = $vars['version'];
|
|
||||||
$_lang = $vars['_lang'];
|
|
||||||
|
|
||||||
// Get module configuration parameters
|
|
||||||
$configTextField = $vars['Text Field Name'];
|
|
||||||
$configPasswordField = $vars['Password Field Name'];
|
|
||||||
$configCheckboxField = $vars['Checkbox Field Name'];
|
|
||||||
$configDropdownField = $vars['Dropdown Field Name'];
|
|
||||||
$configRadioField = $vars['Radio Field Name'];
|
|
||||||
$configTextareaField = $vars['Textarea Field Name'];
|
|
||||||
|
|
||||||
$sidebar = '<p>Sidebar output HTML goes here</p>';
|
|
||||||
return $sidebar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Client Area Output.
|
|
||||||
*
|
|
||||||
* Called when the addon module is accessed via the client area.
|
|
||||||
* Should return an array of output parameters.
|
|
||||||
*
|
|
||||||
* This function is optional.
|
|
||||||
*
|
|
||||||
* @see AddonModule\Client\Controller::index()
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function addonmodule_clientarea($vars)
|
|
||||||
{
|
|
||||||
// Get common module parameters
|
|
||||||
$modulelink = $vars['modulelink']; // eg. index.php?m=addonmodule
|
|
||||||
$version = $vars['version']; // eg. 1.0
|
|
||||||
$_lang = $vars['_lang']; // an array of the currently loaded language variables
|
|
||||||
|
|
||||||
// Get module configuration parameters
|
|
||||||
$configTextField = $vars['Text Field Name'];
|
|
||||||
$configPasswordField = $vars['Password Field Name'];
|
|
||||||
$configCheckboxField = $vars['Checkbox Field Name'];
|
|
||||||
$configDropdownField = $vars['Dropdown Field Name'];
|
|
||||||
$configRadioField = $vars['Radio Field Name'];
|
|
||||||
$configTextareaField = $vars['Textarea Field Name'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch and handle request here. What follows is a demonstration of one
|
|
||||||
* possible way of handling this using a very basic dispatcher implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
|
||||||
|
|
||||||
$dispatcher = new ClientDispatcher();
|
|
||||||
return $dispatcher->dispatch($action, $vars);
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* WHMCS SDK Sample Addon Module Hooks File
|
|
||||||
*
|
|
||||||
* Hooks allow you to tie into events that occur within the WHMCS application.
|
|
||||||
*
|
|
||||||
* This allows you to execute your own code in addition to, or sometimes even
|
|
||||||
* instead of that which WHMCS executes by default.
|
|
||||||
*
|
|
||||||
* @see https://developers.whmcs.com/hooks/
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) WHMCS Limited 2017
|
|
||||||
* @license http://www.whmcs.com/license/ WHMCS Eula
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Require any libraries needed for the module to function.
|
|
||||||
// require_once __DIR__ . '/path/to/library/loader.php';
|
|
||||||
//
|
|
||||||
// Also, perform any initialization required by the service's library.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a hook with WHMCS.
|
|
||||||
*
|
|
||||||
* This sample demonstrates triggering a service call when a change is made to
|
|
||||||
* a client profile within WHMCS.
|
|
||||||
*
|
|
||||||
* For more information, please refer to https://developers.whmcs.com/hooks/
|
|
||||||
*
|
|
||||||
* add_hook(string $hookPointName, int $priority, string|array|Closure $function)
|
|
||||||
*/
|
|
||||||
add_hook('ClientEdit', 1, function(array $params) {
|
|
||||||
try {
|
|
||||||
// Call the service's function, using the values provided by WHMCS in
|
|
||||||
// `$params`.
|
|
||||||
} catch (Exception $e) {
|
|
||||||
// Consider logging or reporting the error.
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,32 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace WHMCS\Module\Addon\AddonModule\Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample Client Area Dispatch Handler
|
|
||||||
*/
|
|
||||||
class ClientDispatcher {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch request.
|
|
||||||
*
|
|
||||||
* @param string $action
|
|
||||||
* @param array $parameters
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function dispatch($action, $parameters)
|
|
||||||
{
|
|
||||||
if (!$action) {
|
|
||||||
// Default to index if no action specified
|
|
||||||
$action = 'index';
|
|
||||||
}
|
|
||||||
|
|
||||||
$controller = new Controller();
|
|
||||||
|
|
||||||
// Verify requested action is valid and callable
|
|
||||||
if (is_callable(array($controller, $action))) {
|
|
||||||
return $controller->$action($parameters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace WHMCS\Module\Addon\AddonModule\Client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sample Client Area Controller
|
|
||||||
*/
|
|
||||||
class Controller {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Index action.
|
|
||||||
*
|
|
||||||
* @param array $vars Module configuration parameters
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function index($vars)
|
|
||||||
{
|
|
||||||
// Get common module parameters
|
|
||||||
$modulelink = $vars['modulelink']; // eg. addonmodules.php?module=addonmodule
|
|
||||||
$version = $vars['version']; // eg. 1.0
|
|
||||||
$LANG = $vars['_lang']; // an array of the currently loaded language variables
|
|
||||||
|
|
||||||
// Get module configuration parameters
|
|
||||||
$configTextField = $vars['Text Field Name'];
|
|
||||||
$configPasswordField = $vars['Password Field Name'];
|
|
||||||
$configCheckboxField = $vars['Checkbox Field Name'];
|
|
||||||
$configDropdownField = $vars['Dropdown Field Name'];
|
|
||||||
$configRadioField = $vars['Radio Field Name'];
|
|
||||||
$configTextareaField = $vars['Textarea Field Name'];
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'pagetitle' => 'Sample Addon Module',
|
|
||||||
'breadcrumb' => array(
|
|
||||||
'index.php?m=addonmodule' => 'Sample Addon Module',
|
|
||||||
),
|
|
||||||
'templatefile' => 'publicpage',
|
|
||||||
'requirelogin' => false, // Set true to restrict access to authenticated client users
|
|
||||||
'forcessl' => false, // Deprecated as of Version 7.0. Requests will always use SSL if available.
|
|
||||||
'vars' => array(
|
|
||||||
'modulelink' => $modulelink,
|
|
||||||
'configTextField' => $configTextField,
|
|
||||||
'customVariable' => 'your own content goes here',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Secret action.
|
|
||||||
*
|
|
||||||
* @param array $vars Module configuration parameters
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function secret($vars)
|
|
||||||
{
|
|
||||||
// Get common module parameters
|
|
||||||
$modulelink = $vars['modulelink']; // eg. addonmodules.php?module=addonmodule
|
|
||||||
$version = $vars['version']; // eg. 1.0
|
|
||||||
$LANG = $vars['_lang']; // an array of the currently loaded language variables
|
|
||||||
|
|
||||||
// Get module configuration parameters
|
|
||||||
$configTextField = $vars['Text Field Name'];
|
|
||||||
$configPasswordField = $vars['Password Field Name'];
|
|
||||||
$configCheckboxField = $vars['Checkbox Field Name'];
|
|
||||||
$configDropdownField = $vars['Dropdown Field Name'];
|
|
||||||
$configRadioField = $vars['Radio Field Name'];
|
|
||||||
$configTextareaField = $vars['Textarea Field Name'];
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'pagetitle' => 'Sample Addon Module',
|
|
||||||
'breadcrumb' => array(
|
|
||||||
'index.php?m=addonmodule' => 'Sample Addon Module',
|
|
||||||
'index.php?m=addonmodule&action=secret' => 'Secret Page',
|
|
||||||
),
|
|
||||||
'templatefile' => 'secretpage',
|
|
||||||
'requirelogin' => true, // Set true to restrict access to authenticated client users
|
|
||||||
'forcessl' => false, // Deprecated as of Version 7.0. Requests will always use SSL if available.
|
|
||||||
'vars' => array(
|
|
||||||
'modulelink' => $modulelink,
|
|
||||||
'configTextField' => $configTextField,
|
|
||||||
'customVariable' => 'your own content goes here',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
<h2>Public Client Area Sample Page</h2>
|
|
||||||
|
|
||||||
<p>This is an example of a public client area page that does not require a login to view.</p>
|
|
||||||
|
|
||||||
<p>All the template variables you define along with some <a href="https://developers.whmcs.com/themes/variables/" target="_blank">additional standard template variables</a> are available within this template.<br>You can use the Smarty <em>{ldelim}debug{rdelim}</em> function call to see a full list.</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
Module Link
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
{$modulelink}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
Config Text Field Value
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
{$configTextField}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
Custom Variable
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
{$customVariable}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="{$modulelink}&action=secret" class="btn btn-default">
|
|
||||||
<i class="fa fa-lock"></i>
|
|
||||||
Go to page that requires authentication
|
|
||||||
</a>
|
|
||||||
</p>
|
|
|
@ -1,45 +0,0 @@
|
||||||
<h2>Secret Client Area Sample Page</h2>
|
|
||||||
|
|
||||||
<p>This is an example of a client area page that requires authentication to access.</p>
|
|
||||||
|
|
||||||
<p>You will have either been prompted to login or already have an active login state to access this page.</p>
|
|
||||||
|
|
||||||
<p>All the template variables you define along with some <a href="https://developers.whmcs.com/themes/variables/" target="_blank">additional standard template variables</a> are available within this template.<br>You can use the Smarty <em>{ldelim}debug{rdelim}</em> function call to see a full list.</p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
Module Link
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
{$modulelink}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
Config Text Field Value
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
{$configTextField}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-3">
|
|
||||||
Custom Variable
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
{$customVariable}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="{$modulelink}" class="btn btn-default">
|
|
||||||
<i class="fa fa-arrow-left"></i>
|
|
||||||
Return to addon module default page
|
|
||||||
</a>
|
|
||||||
</p>
|
|
|
@ -1,44 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* WHMCS Sample Addon Module Test
|
|
||||||
*
|
|
||||||
* Sample PHPUnit test that asserts the fundamental requirements of a WHMCS
|
|
||||||
* module, ensuring that the required config function is defined and contains
|
|
||||||
* the required array keys.
|
|
||||||
*
|
|
||||||
* This is by no means intended to be a complete test, and does not exercise any
|
|
||||||
* of the actual functionality of the functions within the module. We strongly
|
|
||||||
* recommend you implement further tests as appropriate for your module use
|
|
||||||
* case.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) WHMCS Limited 2017
|
|
||||||
* @license http://www.whmcs.com/license/ WHMCS Eula
|
|
||||||
*/
|
|
||||||
class WHMCSModuleTest extends PHPUnit_Framework_TestCase
|
|
||||||
{
|
|
||||||
/** @var string $moduleName */
|
|
||||||
protected $moduleName = 'addonmodule';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asserts the required config options function is defined.
|
|
||||||
*/
|
|
||||||
public function testRequiredConfigOptionsFunctionExists()
|
|
||||||
{
|
|
||||||
$this->assertTrue(function_exists($this->moduleName . '_config'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asserts the required config option array keys are present.
|
|
||||||
*/
|
|
||||||
public function testRequiredConfigOptionsParametersAreDefined()
|
|
||||||
{
|
|
||||||
$result = call_user_func($this->moduleName . '_config');
|
|
||||||
|
|
||||||
$this->assertArrayHasKey('name', $result);
|
|
||||||
$this->assertArrayHasKey('description', $result);
|
|
||||||
$this->assertArrayHasKey('author', $result);
|
|
||||||
$this->assertArrayHasKey('language', $result);
|
|
||||||
$this->assertArrayHasKey('version', $result);
|
|
||||||
$this->assertArrayHasKey('fields', $result);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
// This is the bootstrap for PHPUnit testing.
|
|
||||||
|
|
||||||
if (!defined('WHMCS')) {
|
|
||||||
define('WHMCS', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include the WHMCS module.
|
|
||||||
require_once __DIR__ . '/../modules/addons/addonmodule/addonmodule.php';
|
|
24
whmcs.json
24
whmcs.json
|
@ -1,32 +1,30 @@
|
||||||
{
|
{
|
||||||
"schema": "1.0",
|
"schema": "1.0",
|
||||||
"type": "whmcs-addons",
|
"type": "whmcs-addons",
|
||||||
"name": "sample-addon-module",
|
"name": "accounting",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"category": "addon",
|
"category": "addon",
|
||||||
"description": {
|
"description": {
|
||||||
"name": "Sample Addon Module",
|
"name": "Account selector",
|
||||||
"tagline": "An addon module allows you to add additional functionality to WHMCS.",
|
"tagline": "A module for WHMCS to associate invoice items with accounting accounts",
|
||||||
"long": "This sample file demonstrates how an addon module for WHMCS should be structured and exercises all supported functionality.",
|
"long": "This module allows you to associate invoice items with accounting accounts.",
|
||||||
"features": [
|
"features": [
|
||||||
"Provide both client and admin facing user interfaces",
|
"Admin area interface to select accounting accounts for invoice items",
|
||||||
"Utilize hook functionality within WHMCS"
|
"Admin area interface to set up accounting accounts"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"logo": {
|
"logo": {
|
||||||
"filename": "logo.png"
|
"filename": "logo.png"
|
||||||
},
|
},
|
||||||
"support": {
|
"support": {
|
||||||
"homepage": "https:\/\/www.whmcs.com\/",
|
"homepage": "https:\/\/kumi.systems\/",
|
||||||
"learn_more": "https:\/\/www.whmcs.com\/tour",
|
"email": "support@kumi.systems",
|
||||||
"email": "support@whmcs.com",
|
"support_url": "https:\/\/kumi.support\/"
|
||||||
"support_url": "https:\/\/support.whmcs.com\/",
|
|
||||||
"docs_url": "https:\/\/developers.whmcs.com\/addon-modules\/"
|
|
||||||
},
|
},
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "WHMCS",
|
"name": "Kumi Systems e.U.",
|
||||||
"homepage": "https:\/\/www.whmcs.com\/"
|
"homepage": "https:\/\/kumi.systems\/"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue