<?php

/*
		Functions that call be rewritten according to your needs for DNS and Email forwarding management
		See @https://support.netim.com/en/docs/whmcs/advanced-features/rewrite-module-features  
	*/

// -------------------------------------------------------------------------------------------------
// This function is executed when WHMCS gets the email forwarding list to be displayed in client area
// The code below is designed for the email forwarding service at NETIM
// Replace the code for your own provider if any
// -------------------------------------------------------------------------------------------------
/**
 * Retreive the list of email forwarding to be displayed in the client area
 *
 * @param array 		$object string The object on which the request is done
 */
if (!function_exists('netim_GetEmailForwarding_custom')) {
    function netim_GetEmailForwarding_custom($params)
    {

        $params = injectDomainObjectIfNecessary($params);
        $values = [];

        # Domain Details
        $domain       = isset($params["domain"]) ? $params["domain"] : $params["domainname"];
        $domainACE = isset($params["domain_punycode"]) ? $params["domain_punycode"] : idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII);

        # Get API
        $apiArray = Netim\Core\getApi(array_merge($params));
        if (isset($apiArray["api"]))
            $api = $apiArray["api"];
        else
            return $apiArray;

        # Get email forwarding
        try {
            $mails = $api->queryMailFwdList($domainACE);

            $counter = 0;
            foreach ($mails as $value) {
                $box = explode("@", $value->mailBox);
                if (!empty($value->mailBox) && !empty($value->recipients)) {
                    $values[$counter]["prefix"] = $box[0];
                    $values[$counter]["forwardto"] = $value->recipients;
                    $counter++;
                }
            }
        } catch (Netim\NetimAPIException $fault) {
            $values["error"] = $fault->getMessage();
        }

        # Log API request
        netim_logAPIRequest($domain, $api, __FUNCTION__);

        # Log function call in debug mode
        netim_log(__FUNCTION__, $params, $values);

        return $values;
    }
}

// -------------------------------------------------------------------------------------------------
// This function is executed when WHMCS saves the email forwarding list in client area
// The code below is designed for the email forwarding service at NETIM
// Replace the code for your own provider if any
// -------------------------------------------------------------------------------------------------
if (!function_exists('netim_SaveEmailForwarding_custom')) {
    function netim_SaveEmailForwarding_custom($params)
    {

        $params = injectDomainObjectIfNecessary($params);
        $values = [];
        $current = [];

        # Log function call in debug mode
        netim_log(__FUNCTION__, $params, $values);

        # Domain Details
        $domain       = isset($params["domain"]) ? $params["domain"] : $params["domainname"];
        $domainACE = isset($params["domain_punycode"]) ? $params["domain_punycode"] : idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII);

        # Get API
        $apiArray = Netim\Core\getApi(array_merge($params));
        if (isset($apiArray["api"]))
            $api = $apiArray["api"];
        else
            return $apiArray;

        try {
            # Get email forwarding
            $mails = $api->queryMailFwdList($domainACE);

            $counter = 0;
            foreach ($mails as $value) {
                $box = explode("@", $value->mailBox);
                if (!empty($value->mailBox) && !empty($value->recipients)) {
                    $current[$counter]["email"] = $value->mailBox;
                    $current[$counter]["prefix"] = $box[0];
                    $current[$counter]["forwardto"] = $value->recipients;
                    $counter++;
                }
            }

            # Save email forwarding
            for ($i = 0; $i < count($params["prefix"]); $i++) {
                $action = "";

                if ($params["prefix"][$i] == "" || $params["forwardto"][$i] == "")
                    $action = "DELETE";
                else if (!isset($current[$i]["prefix"]))
                    $action = "ADD";
                else if ($current[$i]["prefix"] != $params["prefix"][$i] || $current[$i]["forwardto"] != $params["forwardto"][$i])
                    $action = "UPDATE";

                if ($action == "DELETE" || $action == "UPDATE") {
                    if (isset($current[$i]["email"])) {
                        $api->domainMailFwdDelete($current[$i]["email"]);
                        netim_logAPIRequest($domain, $api, __FUNCTION__);
                    }
                }

                if ($action == "UPDATE" || $action == "ADD") {
                    $api->domainMailFwdCreate($params["prefix"][$i] . "@" . $domainACE, $params["forwardto"][$i]);
                    netim_logAPIRequest($domain, $api, __FUNCTION__);
                }
            }
        } catch (Netim\NetimAPIException $fault) {
            $values["error"] = $fault->getMessage();
        }

        if (isset($values["error"]))
            netim_logAPIRequest($domain, $api, __FUNCTION__);

        return $values;
    }
}

// -------------------------------------------------------------------------------------------------
// This function is executed when WHMCS get the DNS zone to be displayed in client area
// The code below is designed for the DNS zone management at NETIM
// Replace the code for your own DNS provider if any
// -------------------------------------------------------------------------------------------------
if (!function_exists('netim_GetDNS_custom')) {
    function netim_GetDNS_custom($params)
    {

        $params = injectDomainObjectIfNecessary($params);
        $hostrecords = [];

        # Domain Details
        $domain       = isset($params["domain"]) ? $params["domain"] : $params["domainname"];
        $domainACE = isset($params["domain_punycode"]) ? $params["domain_punycode"] : idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII);

        # Get API
        $apiArray = Netim\Core\getApi(array_merge($params));
        if (isset($apiArray["api"]))
            $api = $apiArray["api"];
        else
            return $apiArray;

        try {
            # Get DNS records
            $domZone = $api->queryZoneList($domainACE);
            netim_logAPIRequest($domain, $api, __FUNCTION__);
            # Get URL redirect
            $domRedirect = $api->queryWebFwdList($domainACE);
            netim_logAPIRequest($domain, $api, __FUNCTION__);
            $sld = explode(".", $domain)[0];
            # Build DNS zone records
            foreach ($domZone as $value) {
                // Found a subdomain ?
                $tab = explode(".$sld", $value->host);
                if (count($tab) > 1) {
                    $h = $tab[0];
                } else
                    $h = "";
                $options = $value->options;
                $defaultTTL = 86400;
                if (is_object($options)) {
                    $options = (array) $options;
                }
                if (strtoupper($value->type) == "CNAME" || strtoupper($value->type) == "MX" || strtoupper($value->type) == "TXT")
                    $hostrecords[] = array("hostname" => $h, "type" => strtoupper($value->type), "address" => $value->value, "priority" => $options['priority'], "ttl" => $options['ttl'] != 0 ? $options['ttl'] : $defaultTTL);
                else if ($value->type == "A") {
                    $find = false;
                    foreach ($domRedirect as $val) {
                        $tab2 = explode(".", $val->FQDN);
                        $h2 = $tab2[0];
                        if ($h == $h2) {
                            if ($val->type == "MASKED")
                                $hostrecords[] = array("hostname" => $h, "type" => "FRAME", "address" => $val->options->protocol . "://" . $val->target, "ttl" => $options['ttl'] != 0 ? $options['ttl'] : $defaultTTL);
                            else
                                $hostrecords[] = array("hostname" => $h, "type" => "URL", "address" => $val->options->protocol . "://" . $val->target, "ttl" => $options['ttl'] != 0 ? $options['ttl'] : $defaultTTL);
                            $find = true;
                        }
                    }

                    if (!$find)
                        $hostrecords[] = array("hostname" => $h, "type" => strtoupper($value->type), "address" => $value->value, "ttl" => $options['ttl'] != 0 ? $options['ttl'] : $defaultTTL);
                } else if ($value->type != "NS") {
                    $hostrecords[] = array("hostname" => $h, "type" => strtoupper($value->type), "address" => $value->value, "ttl" => $options['ttl'] != 0 ? $options['ttl'] : $defaultTTL);
                }
            }
        } catch (Netim\NetimAPIException $fault) {
            // Don't report error if the domain doesn't use our nameservers
            if (!preg_match("#E12-M1220#", $fault->getMessage())) {
                netim_logAPIRequest($domain, $api, __FUNCTION__);
                $hostrecords["error"] = $fault->getMessage();
            }
        }

        # Log function call in debug mode
        netim_log(__FUNCTION__, $params, $hostrecords);
        return $hostrecords;
    }
}

// -------------------------------------------------------------------------------------------------
// This function is executed when WHMCS saves the DNS zone in client area
// The code below is designed for the DNS zone management at NETIM
// Replace the code for your own DNS provider if any
// -------------------------------------------------------------------------------------------------
if (!function_exists('netim_SaveDNS_custom')) {
    function netim_SaveDNS_custom($params)
    {
        $params = injectDomainObjectIfNecessary($params);
        $currentDnsRecords = [];
        $newDnsRecords = $params["dnsrecords"];


        # Domain Details
        $domain       = isset($params["domain"]) ? $params["domain"] : $params["domainname"];
        $domainACE = isset($params["domain_punycode"]) ? $params["domain_punycode"] : idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII);

        # Get API
        $apiArray = Netim\Core\getApi(array_merge($params));
        if (isset($apiArray["api"]))
            $api = $apiArray["api"];
        else
            return $apiArray;

        # Get current records
        $currentDnsRecords = netim_GetDNS_custom($params);

        # Update records if there is a change
        $log = "";
        try {
            for ($i = 0; $i < count($newDnsRecords); $i++) {
                $action = "NOCHANGE";
                $currentFQDN =    $currentDnsRecords[$i]["hostname"] . ".$domainACE";
                $newFQDN =    $newDnsRecords[$i]["hostname"] . ".$domainACE";
                if (!isset($newDnsRecords[$i]["recid"]))
                    $newDnsRecords[$i]["recid"] = 0;

                if ($newDnsRecords[$i]["address"] == "" && isset($currentDnsRecords[$i]))
                    $action = "DELETE";
                else if ($newDnsRecords[$i]["address"] != "" && !isset($currentDnsRecords[$i]))
                    $action = "ADD";
                else if ($newDnsRecords[$i]["address"] == "" && !isset($currentDnsRecords[$i]))
                    $action = "NOCHANGE";
                else if ($newDnsRecords[$i]["hostname"] != $currentDnsRecords[$i]["hostname"] || $newDnsRecords[$i]["type"] != $currentDnsRecords[$i]["type"] || $newDnsRecords[$i]["address"] != $currentDnsRecords[$i]["address"] || ($currentDnsRecords[$i]["type"] == "MX" && $newDnsRecords[$i]["priority"] != $currentDnsRecords[$i]["priority"]) || ($newDnsRecords[$i]["recid"] != "0"  && $currentDnsRecords[$i]["ttl"] != $newDnsRecords[$i]["recid"]))
                    $action = "UPDATE";

                $log .= "Record #$i " . $newDnsRecords[$i]["hostname"] . " IN " . $newDnsRecords[$i]["type"] . " " . $newDnsRecords[$i]["address"] . " => $action\n";

                if ($action == "DELETE" || $action == "UPDATE") {
                    if (in_array($currentDnsRecords[$i]["type"], ["FRAME", "URL"]))
                        $api->domainWebFwdDelete($currentFQDN);
                    else
                        $api->domainZoneDelete($domainACE, $currentDnsRecords[$i]["hostname"], $currentDnsRecords[$i]["type"], $currentDnsRecords[$i]["address"]);
                    netim_logAPIRequest($domain, $api, __FUNCTION__);
                }

                if ($action == "UPDATE" || $action == "ADD") {
                    if (in_array($newDnsRecords[$i]["type"], ["FRAME", "URL"])) {
                        $url = parse_url($newDnsRecords[$i]["address"]);
                        $protocol = $url["scheme"];
                        if (empty($protocol))
                            $protocol = "http";

                        $header = ($newDnsRecords[$i]["type"] == "FRAME" ? "" : 301);
                        $type = ($newDnsRecords[$i]["type"] == "FRAME" ? "MASKED" : "DIRECT");
                        $structOptionsFwd = ["header" => $header, "protocol" => $protocol, "title" => "", "parking" => ""];
                        $api->domainWebFwdCreate($newFQDN, $newDnsRecords[$i]["address"], $type, $structOptionsFwd);
                    } else {
                        switch ($newDnsRecords[$i]["type"]) {
                            case "MXE": // Not supported
                                $newDnsRecords[$i]["type"] = "MX"; // Translate to MX
                            case "MX": //Ensure that a priority is set
                                if (!empty($newDnsRecords[$i]["priority"]) || !is_numeric($newDnsRecords[$i]["priority"]))
                                    $newDnsRecords[$i]["priority"] = 10;
                        }

                        $structOptionsZone = ["service" => "", "protocol" => "", "ttl" => $newDnsRecords[$i]["recid"], "weight" => "", "port" => "", "priority" => ($newDnsRecords[$i]["type"] == "MX" ? $newDnsRecords[$i]["priority"] : "")];


                        if ($newDnsRecords[$i]["type"] == "CAA") {
                            $structOptionsZone = $structOptionsZone + ["flag" => 0, "tag" => "issuewild"];
                        }
                        $api->domainZoneCreate($domainACE, $newDnsRecords[$i]["hostname"], $newDnsRecords[$i]["type"], $newDnsRecords[$i]["address"], $structOptionsZone);
                    }

                    netim_logAPIRequest($domain, $api, __FUNCTION__);
                }
            }
        } catch (Netim\NetimAPIException $fault) {
            $values["error"] = $fault->getMessage();

            # Record the API error
            netim_logAPIRequest($domain, $api, __FUNCTION__);

            # Record the error for the debug mode result
            $log .= "Error #$i => " . $values["error"];

            # Restore back the delete record if any
            if ($action == "UPDATE") {
                try {
                    $structOptionsZone = ["service" => "", "protocol" => "", "ttl" => "", "weight" => "", "port" => "", "priority" => ($currentDnsRecords[$i]["type"] == "MX" ? $currentDnsRecords[$i]["priority"] : "")];
                    $api->domainZoneCreate($domainACE, $currentDnsRecords[$i]["hostname"], $currentDnsRecords[$i]["type"], $currentDnsRecords[$i]["address"], $structOptionsZone);
                    netim_logAPIRequest($domain, $api, __FUNCTION__);
                } catch (Netim\NetimAPIException $fault) {
                }
            }
        }

        # Log function call in debug mode
        netim_log(__FUNCTION__, $params, $log);

        return $values;
    }
}

// --------------------------------------------------------------------------
// This function is executed when NETIM approves a domain name registration
// --------------------------------------------------------------------------
if (!function_exists('netim_PostRegisterDomain')) {
    function netim_PostRegisterDomain($domainid)
    {
        // Put your very own code here
    }
}

// --------------------------------------------------------------------------
// This function is executed when NETIM approves a domain name transfer
// --------------------------------------------------------------------------
if (!function_exists('netim_PostTransferDomain')) {
    function netim_PostTransferDomain($domainid)
    {
        // Put your very own code here
    }
}
