To achieve our goal, we'll use Composer - the PHP dependency manager and the mgufrone/cpanel-whm. package open sourced by Mochamad Gufron
Let's start by cloning the package into a new folder on a WHM server.
composer require gufy/cpanel-whm:dev-master
To test it out, in the root folder of your project create a new PHP file, require vendor/autoload
and try listing the cPanel accounts on your server.
require ('vendor/autoload.php');
$cpanel = new \Gufy\CpanelPhp\Cpanel([
'host' => 'https://myhost.tld:2087',
'username' => 'root',
'auth_type' => 'password', // there is also an option to use "hash"
'password' => 'password', // if you use hash, get the value from WHM's Remote Access Key if not use the root password here
]);
$accounts = $cpanel->listaccts();
print_r($accounts);
If you received a JSON string with all cPanel accounts from your server, then the authentication process worked perfectly.
An important aspect when working with the WHM API is that there are different versions of it, so you need to figure out which one is best for whatever it is that you want to accomplish.
WHM has cPanel API 1 (the version I was using in the original article - from 2014)
, cPanel API 2 (newer but now deprecated)
and UAPI (the latest one)
.
The gufy/cpanel-whm
package provides an interface for interacting with either of these APIs so let's get back to our file and define some constants for each.
Then we will create a new database under one of our cPanel accounts. One more thing to remember is that if you use database prefixes on your instance, you'll need to pass that prefix too.
define("CPANEL_API_1", 1);
define("CPANEL_API_2", 2);
define("UAPI", 3);
//parameters: API Version, Action Class, Action name, cPanel account username, parameters to be passed to function
//remember to pass the prefix
$data = $cpanel->execute_action(UAPI, 'Mysql', 'create_database', 'cpanel_username', ['name'=>'prefix_anewdb']);
//result should look similar to this: //{"func":"create_database","result":{"metadata":{},"data":null,"errors":null,"status":1,"messages":null},"apiversion":3,"module":"Mysql"}
Next step is to create a new user and grant him access to do anything with that database - GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%' WITH GRANT OPTION;
//create the new user!
$usr = $cpanel->execute_action(
UAPI,
'Mysql',
'create_user',
'cpanel_username',
[
'name'=>'prefix_anewusr',
'password'=>'aSecretP@@55'
]
);
//grant everything
$grant = $cpanel->execute_action(
UAPI,
'Mysql',
'set_privileges_on_database',
'cpanel_username',
[
'user'=>'prefix_anewusr',
'database'=>'prefix_anewdb',
'privileges'=>'ALL PRIVILEGES'
]
);
To create new email accounts, make use of the add_pop
function.
//parameters: API_VERSION, Action Class, Action name, cPanel account username, [new email, new password, quota in MB, the domain of the cPanel account, flag for skipping the update of the email accounts database's cache.]
$new_email = $cpanel->execute_action(
UAPI,
'Email',
'add_pop',
'cpanel_username',
array(
'email' => 'anewuser',
'password' => 'aSecretP@@55',
'quota' => '0',
'domain' => 'mydomain.tld',
'skip_update_db' => '0',
)
);
To create new sub-domains on an existing account, UAPI
doesn't yet have an implementation so we will use the API Version 2 in order to achieve the same result.
//parameters: API_VERSION, Action Class, Action name, cPanel account username, [subdomain, parentdomain, the root directory of this new subdomain, flag for removing the dots (.) from the domain value.]
$subdomain = $cpanel->execute_action(
CPANEL_API_2,
'SubDomain',
'addsubdomain',
'cpanel_username',
array(
'domain' => 'mynewsubdomain',
'rootdomain' => 'mydomain.tld',
'dir' => '/public_html/directory_name',
'disallowdot' => '1',
)
);
Hope you find this useful! Let me know your thoughts in the comments area
Many hosting providers use cPanel and this tutorial comes as a helper for those of you who need to manage various server aspects with PHP. I will show you how to create new sub-domains, databases and email accounts on a cPanel driven server, from your PHP code. In order to be able to talk back and forth with the cPanel API you'll need the cPanel XMLAPI Client Class which you can find on GitHub
<?php
$cpanelusr = 'username';
$cpanelpass = 'password';
$xmlapi = new xmlapi('127.0.0.1');
$xmlapi->set_port( 2083 );
$xmlapi->password_auth($cpanelusr,$cpanelpass);
$xmlapi->set_debug(0); //output actions in the error log 1 for true and 0 false
$result = $xmlapi->api1_query($cpanelusr, 'SubDomain', 'addsubdomain', array('subdomainname','domain.com',0,0, '/public_html/subdomainname'));
?>
<?php
$cpanelusr = 'username';
$cpanelpass = 'password';
$xmlapi2 = new xmlapi('127.0.0.1');
$xmlapi2->set_port( 2083 );
$xmlapi2->password_auth($cpanelusr,$cpanelpass);
$xmlapi2->set_debug(0); //output actions in the error log 1 for true and 0 false
//the actual $databasename and $databaseuser will contain the cpanel prefix for a particular account. Ex: prefix_dbname and prefix_dbuser
$databasename = 'db_name';
$databaseuser = 'db_usr'; //be careful this can only have a maximum of 7 characters
$databasepass = 'passwordforthenewuser';
$createdb = $xmlapi2->api1_query($cpanelusr, "Mysql", "adddb", array($databasename)); //creates the database
$usr = $xmlapi2->api1_query($cpanelusr, "Mysql", "adduser", array($databaseuser, $databasepass)); //creates the user
$addusr = $xmlapi2->api1_query($cpanelusr, "Mysql", "adduserdb", array("".$cpanelusr."_".$databasename."", "".$cpanelusr."_".$databaseuser."", 'all')); //gives all privileges to the newly created user on the new db
?>
<?php
//use the same process as above to authenticate
$email_user = "emailusr";
$email_password = "emailusrpass";
$email_domain = "domain.com";
$email_quota = '10';
$addemail $xmlapi->api1_query($cpanelusr, "Email", "addpop", array($email_user, $email_password, $email_quota, $email_domain) );
?>
Of course you can do much more if you study the cPanel API and other cPanel related sources but the above are pieces of code that I've used in the past and they worked for me so I thought I should share them with you guys. Don't hesitate to add more example API calls into the comments section.