Files
wp-multisite-waas/inc/integrations/host-providers/cpanel-api/class-cpanel-api.php
2025-02-09 11:32:57 -07:00

324 lines
7.1 KiB
PHP

<?php
/**
* CPanel API wrapper to send the calls.
*
* @package WP_Ultimo
* @subpackage Integrations/Host_Providers/CPanel_API
* @since 2.0.0
*/
namespace WP_Ultimo\Integrations\Host_Providers\CPanel_API;
use WP_Ultimo\Logger;
/**
* CPanel API wrapper to send the calls.
*/
class CPanel_API {
/**
* Holds the name of the cookis file.
*
* @since 2.0.0
* @var string
*/
private $cookie_file;
/**
* Holds the curl file.
*
* @since 2.0.0
* @var string
*/
private $curlfile;
/**
* Holds the cookie tokens
*
* @since 2.0.0
* @var string
*/
private $cpsess;
/**
* Holds the cPanel url.
*
* @since 2.0.0
* @var string|null
*/
private ?string $homepage = null;
/**
* Holds the execution url.
*
* @since 2.0.0
* @var string|null
*/
private ?string $ex_page = null;
/**
* @var string
*/
private $username;
/**
* @var string
*/
private $password;
/**
* @var string
*/
private $host;
/**
* @var integer
*/
private $port;
/**
* @var boolean
*/
private $log;
/**
* Creates the CPanel_API Object.
*
* @since 1.6.2
* @param string $username cPanel username.
* @param string $password cPanel password. Yep =(.
* @param string $host cPanel URL.
* @param integer $port cPanel port.
* @param boolean $log Log.
*/
public function __construct(
$username,
$password,
$host,
$port = 2083,
$log = false
) {
$this->username = $username;
$this->password = $password;
$this->host = $host;
$this->port = $port;
$this->log = $log;
// Generates the cookie file
$this->generate_cookie();
$this->cookie_file = Logger::get_logs_folder() . 'integration-cpanel-cookie.log';
// Signs up
$this->sign_in();
}
/**
* Generate the Cookie File, that is used to make API requests to CPanel.
*
* @since 1.6.2
* @return void
*/
public function generate_cookie(): void {
wu_log_add('integration-cpanel-cookie', '');
}
/**
* Logs error or success messages.
*
* @since 1.6.2
* @param string $message Message to be logged.
* @return boolean
*/
public function log($message) {
return wu_log_add('integration-cpanel', $message);
}
/**
* Sends the request to the CPanel API.
*
* @since 1.6.2
* @param string $url URL endpoint.
* @param array $params Request parameters to send.
* @return mixed
*/
private function request($url, $params = []) {
if ($this->log) {
$curl_log = fopen($this->curlfile, 'a+');
}
if ( ! file_exists($this->cookie_file)) {
try {
fopen($this->cookie_file, 'w');
} catch (Exception $ex) {
if ( ! file_exists($this->cookie_file)) {
$this->log($ex . __('Cookie file missing.', 'wp-ultimo'));
return false;
}
}
} elseif ( ! is_writable($this->cookie_file)) {
$this->log(__('Cookie file not writable', 'wp-ultimo'));
return false;
}
$ch = curl_init();
$curl_opts = [
CURLOPT_URL => $url,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_COOKIEJAR => realpath($this->cookie_file),
CURLOPT_COOKIEFILE => realpath($this->cookie_file),
CURLOPT_HTTPHEADER => [
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0',
'Host: ' . $this->host,
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language: en-US,en;q=0.5',
'Accept-Encoding: gzip, deflate',
'Connection: keep-alive',
'Content-Type: application/x-www-form-urlencoded',
],
];
if ( ! empty($params)) {
$curl_opts[ CURLOPT_POST ] = true;
$curl_opts[ CURLOPT_POSTFIELDS ] = $params;
}
if ($this->log) {
$curl_opts[ CURLOPT_STDERR ] = $curl_log;
$curl_opts[ CURLOPT_FAILONERROR ] = false;
$curl_opts[ CURLOPT_VERBOSE ] = true;
}
curl_setopt_array($ch, $curl_opts);
$answer = curl_exec($ch);
if (curl_error($ch)) {
// translators: %s is the cURL error.
$this->log(sprintf(__('cPanel API Error: %s', 'wp-ultimo'), curl_error($ch)));
return false;
}
curl_close($ch);
if ($this->log) {
fclose($curl_log);
}
return (@gzdecode($answer)) ? gzdecode($answer) : $answer; // phpcs:ignore
}
/**
* Get the base URL to make the calls.
*
* @since 2.0.0
*/
private function get_base_url(): string {
return sprintf('https://%s:%s', $this->host, $this->port);
}
/**
* Signs in on the cPanel.
*
* @since 1.6.2
* @return boolean
*/
private function sign_in() {
$url = $this->get_base_url() . '/login/?login_only=1';
$url .= '&user=' . $this->username . '&pass=' . urlencode($this->password);
$reply = $this->request($url);
$reply = json_decode((string) $reply, true);
if (isset($reply['status']) && $reply['status'] == 1) { // phpcs:ignore
$this->cpsess = $reply['security_token'];
$this->homepage = $this->get_base_url() . $reply['redirect'];
$this->ex_page = $this->get_base_url() . "/{$this->cpsess}/execute/";
} else {
return $this->log(__('Cannot connect to your cPanel server : Invalid Credentials', 'wp-ultimo'));
}
}
/**
* Executes API calls, taking the request to the right API version
*
* @since 1.6.2
* @throws Exception Throwns exception when the api is invalid.
* @param string $api API version.
* @param string $module Module name, to build the endpoint.
* @param string $function Endpoint function to call.
* @param array $parameters Parameters to the API endpoint.
* @return boolean
*/
public function execute($api, $module, $function, array $parameters = []) {
switch ($api) {
case 'api2':
return $this->api2($module, $function, $parameters);
case 'uapi':
return $this->uapi($module, $function, $parameters);
default:
throw new Exception('Invalid API type : api2 and uapi are accepted', 1);
}
}
/**
* Send the request if the API being used is the UAPI (newer version)
*
* @since 1.6.2
* @param string $module Module name, to build the endpoint.
* @param string $function Endpoint function to call.
* @param array $parameters Parameters to the API endpoint.
* @return mixed
*/
public function uapi($module, $function, array $parameters = []) {
if (count($parameters) < 1) {
$parameters = '';
} else {
$parameters = (http_build_query($parameters));
}
return json_decode((string) $this->request($this->ex_page . $module . '/' . $function . '?' . $parameters));
}
/**
* Send the request if the API being used is the API2 (older version)
*
* @since 1.6.2
* @param string $module Module name, to build the endpoint.
* @param string $function Endpoint function to call.
* @param array $parameters Parameters to the API endpoint.
* @return mixed
*/
public function api2($module, $function, array $parameters = []) {
if (count($parameters) < 1) {
$parameters = '';
} else {
$parameters = (http_build_query($parameters));
}
$url = $this->get_base_url() . $this->cpsess . '/json-api/cpanel' .
'?cpanel_jsonapi_version=2' .
"&cpanel_jsonapi_func={$function}" .
"&cpanel_jsonapi_module={$module}&" . $parameters;
return json_decode((string) $this->request($url, $parameters));
}
}