Writing cPanel Modules

The most powerful way of integrating your custom applications with cPanel is by writing a Perl module. Using this integration method, you can access cPanel's API systems without using the XML or JSON API, and without using <cpanel> or <?cp > tags. Your application will also process and run much faster.

Basics

cPanel Perl modules are ordinary Perl modules that are placed in a specific directory and use the cPanel namespace.

You need to place your custom cPanel Perl modules in the following directory:

  • /usr/local/cpanel/Cpanel/

Since cPanel modules are parsed internally by the cPanel software, you will not be able to call system-installed modules from your custom modules. Only a few pre-compiled modules (located in /usr/local/cpanel/perl/) and the other modules in the Cpanel:: namespace are available.

If you need to install additional modules, you can place them in:

  • /usr/local/cpanel/perl

Creating API1 Calls

note Note: Please review the API1 documentation before reading this section.

Setting up a module that will make a custom API1 call requires a function that will operate as a constructor. This function needs to use the module's name, suffixed by init(). This function will only need to return output, but it is required in order for the API1 call to work successfully.

The function should resemble the following:

sub Module_init {
	return;
}

In the example above, Module represents the module name you wish to use.

Once you have set up the required function, you can use your module to print or return data. However, if you are returning more than a string, you will need to use API2.

A sample function within a cPanel module can be found below. This module simply prints data to the cPanel interface:

sub Module_test {
	print “testing 1 2 3”;
}

Adding Parameters

Passing parameters to an API1 call is exactly like passing parameters inside of any other Perl function. Data passed into the function is passed via the special @_ variable. You can assign $_[array index] to any given variable if you wish to pass parameters to a human-readable variable. For example:

sub Module_printLC {
	my ($string1) = @_;
	print lc( $string1 );
}

If, for example, you wish to pass the <cpanel> tag, you could do so by including:

<cpanel Module=”printLC(TESTING)”>

The example above would print testing to the cPanel interface.

Using Error Messages

In order to raise an error message within a cPanel module, you need to assign the error strings to the following hash:

  • $Cpanel::CPERROR

The key element of this hash should have the same name as the module with which you are working. For example:

sub Module_raiseError {
	$Cpanel::CPERROR{‘module’} = “This is an error message”;
}

In the example above, module represents the module name you wish to use.

The example above would allow you to check for the existance of an error using a <cpanelif> tag. This can be printed and check in the interface by using $CPERROR{'module'} inside your HTML file.

Creating API2 Calls

note Note: Please review the API2 documentation before reading this section.

API2 modules are designed to return data rather than printing it to the cPanel interface. Thus, creating API2 modules is slightly more complicated than creating an API1 module.

In order to enable your cPanel module to make custom API2 calls, you need to create a generic function titled api2() within the module. This function specifies which API2 calls are mapped to which functions. It is also responsible for returning a hash that contains information on how the module works. There are only 2 elements of this hash that need to be returned:

  • func — This element defines the function through which the call is made.
  • engine — This element specifies the output format.
    • note Note: engine will almost always be a hash array.

A sample api2() function can be found below:

sub api2 {
	my $func = shift;
	my %API;
	$API{‘functionName’}{‘func’} = “api2_test”;
	$API{‘functionName’}{‘engine’} = ‘hasharray’;
	return \%{ $API{ $func } };
}

Since the API2 system uses named prameters, the @_ variable will need to be assigned to a hash like so:

sub api2_test {
	my %OPTS = @_;
}

PICK Remember: As a convention, you should use the %OPTS hash for API2 input parameters.

Once you have created this function within your cPanel module, any data passed to the function within a <?cp ?> tag can be accessed as an element of that hash. As an example, assume the <?cp ?> tag has been passed the following information:

<?cp Module::test( %, data, ) number=”5” ?>

In this example, after %OPTS has been properly assigned, you will be able to access the number variable via $OPTS{'number'};. For example:

sub api2_test {
	my %OPTS = @_;
	my $number = $OPTS{‘number’};
}

Returning Data

The API2 system must return a hash reference or an array of hash references if you intend to use the call within <?cp ?> tags. Elements within the returned reference must either be arrays of hash references or scalar variables.

note Note: These restrictions do not apply to cPanel calls made through the XML API system.

Returning a Hash

One acceptable return format for API2 is a normal hash reference. It will need to be formatted like the following example:

{
	key => “value”
}

In the example above, key can be accessed via the <?cp ?> tags when laid out like so:

<?cp Module::function( %, key, ) ?>

The example above will print value when accessed via a web browser.

Returning an Array of Hashes

Another acceptable return format is an array reference of hash references. For example:

[
	{
		key => “value1”
	},
	{
		key => “value2”
	}
]

In the example above, the template will be applied to each element of the array when calling API2 functions via the <?cp ?> tags. In this particular scenario:

<? Module::function( % [br /], key, ) ?>

The example above, when given an array of hashes, will display the following:

value 1
value 2

An Array of Hashes as a Hash Element

Values within hashes do not have to be scalar variables. These values can also be arrays of hashes.

note Note: Nested hash elements and nested arrays cannot be accepted.

Using this method, your data would need to be modeled after the following example:

{
	element => [
			{
				key => “value1”
			},
			{
				key => “value2”
			}
		]
	another_element => “testing”
}

In order to call this data using <?cp ?> tags, you would need to use the following format:

<?cp Module::function( 
  % [br /]%, 
  another_element, 
  element:: KEY-${key}[br /]:
) 
?>

The example above would output the following:

testing
KEY-value1
KEY-value2
Topic revision: r11 - 10 Sep 2009 - 19:00:41 - Main.MattDees
DeveloperResources/ApiBasics.WritingCpanelModules moved from Sandbox.WritingCpanelModules on 03 Sep 2009 - 18:04 by Main.JustinSchaefer - put it back
 

Copyright © cPanel 2000-2009.