Sindbad~EG File Manager
<?php
namespace O2switch\CpanelLib\Service;
use O2switch\CpanelLib\Client\CpanelApi;
use O2switch\CpanelLib\Exception\InvalidCpanelApiResponse;
use O2switch\CpanelLib\Exception\LogicException;
class Mx
{
// MX cases
const NO_MX = 'noMx';
const ONE_MX_LOCAL = 'oneLocalMx';
const ONE_MX_REMOTE = 'oneRemoteMx';
const MULTIPLE_MX = 'mulitpleMx';
// Mail SubDomain cases
const NO_MAIL_SUBDOM = 'noMailSubdomain';
const MULTIPLE_MAIL_SUBDOM = 'mulitpleMailSubdomains';
const ONE_CNAME_TO_DOMAIN = 'oneCnameToMainDomain';
const ONE_CNAME_TO_MAIN_SERVERNAME = 'oneCnameToMainServername';
const ONE_CNAME_TO_REMOTE_DOMAIN = 'oneCnameToRemoteDomain';
const ONE_A_TO_SERVER_IP = 'oneAToServerIp';
const ONE_A_TO_REMOTE_SERVER_IP = 'oneAToRemoteIp';
// Can be used on both cases, when we cant detect or dont expect something.
const UNSUPPORTED = 'unsupported';
/** @var CpanelApi */
private $cpanelApi;
/** @var string */
private $currentServerIp;
/** @var string */
private $currentServerHostname;
public function __construct(CpanelApi $cpanelApi){
$this->cpanelApi = $cpanelApi;
$this->currentServerIp = $cpanelApi->getVar('ip');
$this->currentServerHostname = $cpanelApi->getVar('hostname');
}
/**
* Reconfigure the MX, only if needed, to point to the server with a subdomain.
* @param string $domain
* @param string $mxConfig
* @param string $subdomConfig
* @throws InvalidCpanelApiResponse
* @throws LogicException
*/
public function reconfigureMx(string $domain, string $mxConfig, string $subdomConfig) : void {
if(in_array($mxConfig, [self::UNSUPPORTED, self::ONE_MX_REMOTE, self::MULTIPLE_MX /*,self::NO_MX*/])){
return;
}
// ONE_LOCAL_MX|| NO_MX
$record = $this->getMailSubdomainRecords($domain);
$record = $record[0] ?? [];
$mxSubDomain = 'mail.' . $domain;
if($subdomConfig === self::ONE_CNAME_TO_DOMAIN){
$r = $this->cpanelApi->api2('ZoneEdit', 'remove_zone_record', [
'domain' => $domain,
'line' => $record['line']
]);
if($r === false || !isset($r[0]['result']['status']) || $r[0]['result']['status'] !== 1){
throw new InvalidCpanelApiResponse(sprintf("Error while executing ZoneEdit::remove_zone_record for '%s' deleting CNAME record '%s'", $domain, 'mail.' . $domain));
}
$subdomConfig = self::NO_MAIL_SUBDOM;
}
if($subdomConfig === self::NO_MAIL_SUBDOM){
$r = $this->cpanelApi->api2('ZoneEdit', 'add_zone_record', [
'domain' => $domain,
'name' => 'mail',
'type' => 'A',
'address' => $this->currentServerIp,
'class' => 'IN',
]);
if($r === false || !isset($r[0]['result']['status']) || $r[0]['result']['status'] !== 1){
throw new InvalidCpanelApiResponse(sprintf("Error while executing ZoneEdit::add_zone_record for '%s'", $mxSubDomain));
}
$subdomConfig = self::ONE_A_TO_SERVER_IP;
}
if(in_array($subdomConfig, [self::MULTIPLE_MAIL_SUBDOM, self::ONE_CNAME_TO_REMOTE_DOMAIN, self::ONE_A_TO_REMOTE_SERVER_IP])){
$mxSubDomainPart = 'mail-' . rand(1000,9999);
$mxSubDomain = $mxSubDomainPart . '.' . $domain;
$r = $this->cpanelApi->api2('ZoneEdit', 'add_zone_record', [
'domain' => $domain,
'name' => $mxSubDomainPart,
'type' => 'A',
'address' => $this->currentServerIp,
'class' => 'IN',
]);
if($r === false || !isset($r[0]['result']['status']) || $r[0]['result']['status'] !== 1){
throw new InvalidCpanelApiResponse(sprintf("Error while executing ZoneEdit::add_zone_record for '%s'", $mxSubDomain));
}
$subdomConfig = self::ONE_A_TO_SERVER_IP;
}
if(!in_array($subdomConfig, [self::ONE_CNAME_TO_MAIN_SERVERNAME, self::ONE_A_TO_SERVER_IP])){
throw new \LogicException(sprintf("This part of code should not be accessible. Case '%s' for '%s'.", $subdomConfig, $domain));
}
// Change the MX
$r = $this->cpanelApi->uapi('Email', 'change_mx', [
'domain' => $domain,
'exchanger' => $mxSubDomain,
'oldexchanger' => 'mail.' . $domain,
'priority' => 0,
]);
if(!isset($r['status']) || $r['status'] !== 1){
throw new InvalidCpanelApiResponse(sprintf("Error while executing Email::change_mx from '%s' to '%s'", 'mail.' . $domain, $mxSubDomain));
}
}
/**
* Detect the 'mail' subdomain configuration for the domain and return a string describing the configuration.
* @param string $domain
* @return string
* @throws InvalidCpanelApiResponse
*/
public function detectMailSubdomainConfiguration(string $domain) : string{
$records = $this->getMailSubdomainRecords($domain);
if(count($records) === 0){
return self::NO_MAIL_SUBDOM;
}
if(count($records) > 1){
return self::MULTIPLE_MAIL_SUBDOM;
}
if(!isset($records[0]['type'])){
return self::UNSUPPORTED;
}
if(!isset($records[0]['type'])
|| (strtoupper($records[0]['type']) !== 'CNAME' && strtoupper($records[0]['type']) !== 'A')){
return self::UNSUPPORTED;
}
if(strtoupper($records[0]['type']) === 'A'){
if($records[0]['record'] === $this->currentServerIp){
return self::ONE_A_TO_SERVER_IP;
}
// In case the user have a dedicated IP. Unlikely.
if($records[0]['record'] === gethostbyname($this->currentServerHostname)){
return self::ONE_A_TO_SERVER_IP;
}
return self::ONE_A_TO_REMOTE_SERVER_IP;
}
if($records[0]['record'] === $domain){
return self::ONE_CNAME_TO_DOMAIN;
}
if($records[0]['record'] === $this->currentServerHostname){
return self::ONE_CNAME_TO_MAIN_SERVERNAME;
}
return self::ONE_CNAME_TO_REMOTE_DOMAIN;
}
/**
* Detect the MX Configuration of the domain. Return a string representing the MX Config base on pre-defined use cases.
* @param string $domain
* @return string
* @throws InvalidCpanelApiResponse
*/
public function detectMxConfiguration(string $domain) : string {
$records = $this->cpanelApi->uapi('Email', 'list_mxs', ['domain' => $domain]);
if(!isset($records['status']) || $records['status'] !== 1 || !isset($records['result'])){
throw new InvalidCpanelApiResponse(sprintf("Error while executing SSL::installed_hosts for '%s'", $domain));
}
if(!isset($records['result'][0]) || count($records['result'][0]['entries']) === 0){
return self::NO_MX;
}
if(count($records['result'][0]['entries']) > 1){
return self::MULTIPLE_MX;
}
if($records['result'][0]['local'] === 1){
return self::ONE_MX_LOCAL;
}
if($records['result'][0]['remote'] === 1){
return self::ONE_MX_REMOTE;
}
return self::UNSUPPORTED;
}
private function getMailSubdomainRecords(string $domain) : array {
$records = $this->cpanelApi->api2('ZoneEdit', 'fetchzone_records', [
'domain' => $domain,
'class' => 'IN',
'name' => 'mail.'.$domain.'.',
]);
if($records === false || !is_array($records)){
throw new InvalidCpanelApiResponse(sprintf("Error while executing ZoneEdit::fetchzone_records for '%s'", $domain));
}
return $records;
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists