Sindbad~EG File Manager

Current Path : /opt/nginxhttpd_/vendor/extensions-cpanel/cpanel-development-lib/src/Service/
Upload File :
Current File : //opt/nginxhttpd_/vendor/extensions-cpanel/cpanel-development-lib/src/Service/Mx.php

<?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