<?php

require_once 'classes/RegistrarPlugin.php';
require_once dirname(__FILE__).'/class.planetdomain.php';

/**
* @package Plugins
*/
class PluginPlanetdomain extends RegistrarPlugin {

    function getVariables(){

        $variables = array(
            /*T*/'Plugin Name'/*/T*/ => array (
                                'type'          =>'hidden',
                                'description'   =>/*T*/'How CE sees this plugin (not to be confused with the Signup Name)'/*/T*/,
                                'value'         =>/*T*/'PlanetDomain'/*/T*/
                               ),
            /*T*/'Use testing server'/*/T*/ => array(
                                'type'          =>'yesno',
                                'description'   =>/*T*/'Select Yes if you wish to use PlanetDomain\'s testing environment, so that transactions are not actually made.'/*/T*/,
                                'value'         => 0
                               ),
            /*T*/'Admin Username'/*/T*/ => array(
                                'type'          => 'text',
                                'description'   => /*T*/'Enter your admin username for your PlanetDomain\'s reseller account.'/*/T*/,
                                'value'         => '',
                            ),
            /*T*/'Admin Password'/*/T*/  => array(
                                'type'          => 'password',
                                'description'   => /*T*/'Enter your PlanetDomain reseller Password.'/*/T*/,
                                'value'         => '',
                            ),
            /*T*/'Reseller Id'/*/T*/  => array(
                                'type'          => 'text',
                                'description'   => /*T*/'Enter your PlanetDomain reseller Id.'/*/T*/,
                                'value'         => '',
                            ),
                 'Actions'   => array (
                                'type'          => 'hidden',
                                'description'   => 'Current actions that are active for this plugin',
                                'value'         => 'CheckDomain, DisableRenewal, GetContact, GetInfo, GetNS, Register, SetContact',
                                )
        );

        return $variables;
    }

    function checkDomain($params) {

        // PlanetDomain returns lots of E_NOTICE
        error_reporting(E_ALL & ~E_NOTICE);

        /* We need to specify the operation for PlanetDomain API */

        $operation = "domain.lookup";

        /* Pass the constants to the constructor along with logger */

        $planetdomain = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

        $return = $planetdomain->domain_lookup(strtolower($params['sld'].".".$params['tld']),$operation);

        if ($return == null) {

            $this->logger->log(4, "PlanetDomain Error: Not able to connect to the API.");
            return array(5);

        } else {

            $response = $this->processResponse($return);

            if($response["domain.status"] == "UNAVAILABLE"){

                $this->logger->log(4, "PlanetDomain status: UNAVAILABLE");
                return array(1);

            } elseif($response["domain.status"] == "AVAILABLE") {

                $this->logger->log(4, "PlanetDomain status: AVAILABLE");
                return array(0);

            } else {

                $this->logger->log(4, "PlanetDomain status: CAN NOT CONNECT TO REGISTRY");
                return array(2);
            }

        }

        $this->logger->log(4,"Response From Planet Domain : ".print_r($response,true)." ");

        return array(5);
    }

    function registerDomain($params){

        // PlanetDomain returns lots of E_NOTICE
        error_reporting(E_ALL & ~E_NOTICE);

        $domain = strtolower($params['sld'].".".$params['tld']);
        $tld = strtolower($params['tld']);
        $fullname = $params['RegistrantFirstName']." ".$params['RegistrantLastName'];
        $params['FullName'] = $fullname;
        $params['AUType'] = 'COMPANY'; // default set to company
        $params['ACN'] = '004085616'; // default ACN

        if ($params['Use testing server']) {
            $params['NS1']['hostname'] = "ns1.planetdomain.com";
            $params['NS2']['hostname'] = "ns2.planetdomain.com";
            $params['Custom NS'] = 1;
            for ($i = 3; $i <= 12; $i++) {
                unset($params['NS'.$i]);
            }

            list($NS1IP) = $this->getDefaultServerIP($domain);
            list($NS2IP) = $this->getDefaultServerIP($domain);
        } else {
            if (isset($params['NS1']) && isset($params['NS2'])) {
                $params['NS1']['hostname'] = $params['NS1']['hostname'];
                $params['NS2']['hostname'] = $params['NS2']['hostname'];
                list($NS1IP) = $this->getNSIPByName($params['NS1']['hostname']);
                list($NS2IP) = $this->getNSIPByName($params['NS2']['hostname']);

            } else {
                $this->logger->log(4, "Domain Registration Failed : Error - No NameServers Configured");
                return array(-1, array("You must configure Nameserver1,Nameserver2."));
            }
        }

        $operation = "user.add";

        $planetdomain = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

        /* Domain Username isn't passed by default */
        $query = "SELECT username FROM domains WHERE DomainName=?";
        $result = $this->db->query($query, $params['sld'].".".$params['tld']);
        list ($params['DomainUsername']) = $result->fetch();

        /* Specify the user.add operation for PlanetDomain API */

        /* Make the phone number like +914872353748 */

        $params['RegistrantPhone'] = $this->_validatePhone($params['RegistrantPhone'],$params['RegistrantCountry']);

        $planetDomainUser = array();
        $planetDomainUser['user.lastname'] = $params['RegistrantLastName'];
        $planetDomainUser['user.firstname'] = $params['RegistrantFirstName'];

        if ($params['RegistrantOrganizationName'] != "") {
            $planetDomainUser['user.company'] = $params['RegistrantOrganizationName'];
            $planetDomainUser['user.type'] = 'COMPANY';
        }

        $planetDomainUser['user.address1'] = $params['RegistrantAddress1'];
        $planetDomainUser['user.suburb'] = $params['RegistrantCity'];
        $planetDomainUser['user.postcode'] = $params['RegistrantPostalCode'];
        $planetDomainUser['user.state'] = $params['RegistrantStateProvince'];
        $planetDomainUser['user.country'] = $params['RegistrantCountry'];
        $planetDomainUser['user.phone'] = $params['RegistrantPhone'];
        $planetDomainUser['user.email'] = $params['RegistrantEmailAddress'];
        $planetDomainUser['user.username'] = $params['DomainUsername'];
        $planetDomainUser['user.password'] = $params['DomainPassword'];

        /* Call POST API method user.add to add a User */

        $addUserResult = $planetdomain->addUser($operation,$planetDomainUser);

        $addUserResponse = $this->processResponse($addUserResult);

        $custID = "";

        if($addUserResponse["success"] == 'TRUE'){
            $custID = $addUserResponse["user.id"];
            $this->logger->log(4, "Planet Domain MemberID : ".print_r($custID,true));
        } else {

            $this->logger->log(4, "Planet Domain user.add : Failed");
            return array(-1, array("Domain registration failed: Error - Cant not add a user. Try another username"));

        }

        if($custID != ""){
            $registerData = array();

            $registerData['domain.name'] = $domain;
            $registerData['owner.id'] = $custID;
            $registerData['tech.id'] = $custID;
            $registerData['admin.id'] = $custID;
            $registerData['billing.id'] = $custID;
            $registerData['register.period'] = $params['NumYears'];
            $registerData['ns.name.0'] = $params['NS1']['hostname'];
            $registerData['ns.ip.0'] = $NS1IP;
            $registerData['ns.name.1'] = $params['NS2']['hostname'];
            $registerData['ns.ip.1'] = $NS2IP;

            /* Some special condition parameters for .us TLD */

            if($params['tld'] == 'us'){

                if($params['ExtendedAttributes']['us_purpose'] == "") {

                    $registerData['us.intended_use'] = "P1"; // Default to Business account

                } else {
                    $registerData['us.intended_use'] = $params['ExtendedAttributes']['us_purpose'];
                }

                if($params['ExtendedAttributes']['us_nexus'] == ""){

                    $registerData['us.nexus_category'] = "C11"; // Default to US Citizen

                } else {
                    $registerData['us.nexus_category'] = $params['ExtendedAttributes']['us_nexus'];
                }
            }

            /* Some special parameters required for .au TLDs */

            if ($tld == 'org.au') {

                $auorgtype = $params['ExtendedAttributes']['au_org_type'];

                $registerData['au.org.type'] = $auorgtype;
                $registerData['au.registrant.name'] = $params['FullName'];
                $registerData['au.registrant.state'] = $params['RegistrantStateProvince'];
                $registerData['au.registrant.address'] = $params['RegistrantAddress1'];

                    switch ($auorgtype) {
                        case "INCASSOC":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['au_assoc_num'];
                            break;
                        case "CLUB":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                        case "COMPANY":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['acn'];
                            break;
                        case "TRADING":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['rbn'];
                            break;
                        case "CHARITY":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                        case "NONPROFIT":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                       case "OTHER":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                        }
            }

            if ( ($tld == 'com.au') || ($tld == 'net.au') ) {

                $auorgtype = $params['ExtendedAttributes']['au_org_type'];

                $registerData['au.org.type'] = $auorgtype;
                $registerData['au.registrant.name'] = $params['FullName'];
                $registerData['au.registrant.state'] = $params['RegistrantStateProvince'];
                $registerData['au.registrant.address'] = $params['RegistrantAddress1'];

                    switch ($auorgtype) {
                        case "INCASSOC":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['au_assoc_num'];
                            break;
                        case "COMPANY":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['acn'];
                            break;
                        case "TRADING":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['rbn'];
                            break;
                        case "PARTNERSHIP":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                        case "SOLETRADER":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                       case "FOREIGN":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['rbn'];
                            break;
                       case "TMARKOWNER":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['acn'];
                            $registerData['au.trademark.name'] = $params['ExtendedAttributes']['au_trademark_name'];
                            $registerData['au.trademark.number'] = $params['ExtendedAttributes']['au_trademark_number'];
                            break;
                       case "TMARKAPPLIC":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['acn'];
                            $registerData['au.trademark.name'] = $params['ExtendedAttributes']['au_trademark_name'];
                            $registerData['au.trademark.number'] = $params['ExtendedAttributes']['au_trademark_number'];
                            break;
                       case "STATUTORY":
                            $registerData['au.parliament.act '] = $params['ExtendedAttributes']['au_parliament_act'];
                            break;
                       case "OTHER":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                        }
            }

            if ($tld == 'asn.au') {

                $auorgtype = $params['ExtendedAttributes']['au_org_type'];

                $registerData['au.org.type'] = $auorgtype;
                $registerData['au.registrant.name'] = $params['FullName'];
                $registerData['au.registrant.state'] = $params['RegistrantStateProvince'];
                $registerData['au.registrant.address'] = $params['RegistrantAddress1'];

                    switch ($auorgtype) {
                        case "INCASSOC":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['au_assoc_num'];
                            break;
                        case "UNION":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['au_org_number'];
                            break;
                        case "INDUSTRY":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['au_org_number'];
                            break;
                        case "CLUB":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                       case "OTHER":
                            $registerData['au.registrant.number'] = $params['ExtendedAttributes']['abn'];
                            break;
                        }
            }

            $operation = "domain.register";

            /* Call POST API method domain.register to register a Domain */

            $planetdomain1 = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

            $regDomainResult = $planetdomain1->registerPlanetDomain($operation,$registerData);
            $regDomainResponse = $this->processResponse($regDomainResult);

            if($regDomainResponse["success"] == 'TRUE'){

                $this->logger->log(4, "Planet Domain Registration: SUCCESS");

                if($regDomainResponse["registration.status"] == 'COMPLETE'){

                    return array(1,array("Domain registration completed successfully"));

                } elseif($regDomainResponse["registration.status"] == 'PENDING'){

                    return array(0,array("Domain registration pending"));
                }
                return array(1,array("Domain registered successfully"));
            } else {
                $errordesc = $regDomainResponse["error.desc.0"];
                $errordesc = "Domain registration failed: ".$errordesc;
                return array(-1, array($errordesc));
            }

            $this->logger->log(4, "Domain REG :".print_r($regDomainResult,true));
        } else {
            $this->logger->log(4, "No Member ID Found");
            return array(-1, array("Domain registration failed: Can not retrieve a valid Member ID"));
        }

        return array(-1, array("Domain registration failed: Can not contact Registry"));

    }

    function getContactInformation($params){

        // PlanetDomain returns lots of E_NOTICE
        error_reporting(E_ALL & ~E_NOTICE);

        $operation = "user.info";
        $domain = strtolower($params['sld'].".".$params['tld']);
        $planet = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

        /* Domain Username isn't passed by default */
        $query = "SELECT username FROM domains WHERE DomainName=?";
        $result = $this->db->query($query, $params['sld'].".".$params['tld']);
        list ($params['DomainUsername']) = $result->fetch();

        $contactResult = $planet->userInfo($operation,$params['DomainUsername']);

        $contactResponse = $this->processResponse($contactResult);

        $this->logger->log(4, 'Planet Domain Returned: '.print_r($contactResponse, true));

        $info = array();

        if($contactResponse["success"] == 'TRUE') {
             // some info might not be available when the privacy protection is enabled for the domain
            $info['Registrant']['OrganizationName']  = array($this->user->lang('Organization'), $contactResponse['user.company']);
            $info['Registrant']['FirstName'] = array($this->user->lang('First Name'), $contactResponse['user.firstname']);
            $info['Registrant']['LastName'] = array($this->user->lang('Last Name'), $contactResponse['user.lastname']);
            $info['Registrant']['Address1']  = array($this->user->lang('Address').' 1', $contactResponse['user.address1']);
            $info['Registrant']['Address2']  = array($this->user->lang('Address').' 2', isset($contactResponse['user.address2'])? $contactResponse['user.address2'] : '');
            $info['Registrant']['City']      = array($this->user->lang('City'), $contactResponse['user.suburb']);
            $info['Registrant']['StateProv']  = array($this->user->lang('Province').'/'.$this->user->lang('State'), $contactResponse['user.state']);
            $info['Registrant']['Country']   = array($this->user->lang('Country'), $contactResponse['user.country']);
            $info['Registrant']['PostalCode']  = array($this->user->lang('Postal Code').'/'.$this->user->lang('Zip'), $contactResponse['user.postcode']);
            $info['Registrant']['EmailAddress']   = array($this->user->lang('E-mail'), $contactResponse['user.email']);
            $info['Registrant']['Phone']  = array($this->user->lang('Phone Country Code'), $contactResponse['user.phone']);
            //$info['UserID']  =  $contactResponse['user.id'];

            return $info;

        } else {

            return new NE_Error("Failed to retrieve data from PlanetDomain", 1001);
        }

        return new NE_Error('Error contacting PlanetDomain', 131);

    }

    function setContactInformation($params){

        // PlanetDomain returns lots of E_NOTICE
        error_reporting(E_ALL & ~E_NOTICE);

        $operation = "user.info";
        $domain = strtolower($params['sld'].".".$params['tld']);
        $planet = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

        /* Domain Username isn't passed by default */
        $query = "SELECT username FROM domains WHERE DomainName=?";
        $result = $this->db->query($query, $params['sld'].".".$params['tld']);
        list ($params['DomainUsername']) = $result->fetch();

        $contactResult = $planet->userInfo($operation,$params['DomainUsername']);

        $contactResponse = $this->processResponse($contactResult);

        $this->logger->log(4, 'Planet Domain Returned: '.print_r($contactResponse, true));

        $pdUserID = "";

        if($contactResponse["success"] == 'TRUE') {
            $pdUserID = $contactResponse['user.id'];

        } else {

            return new NE_Error("Failed to get User ID", 1001);
        }

        if($pdUserID != "") {
            $operation = "user.update";

            $params['Registrant_Phone'] = $this->_validatePhone($params['Registrant_Phone'],$params['Registrant_Country']);
            unset($planetDomainUser);
            $planetDomainUser = array();
            $planetDomainUser['user.id'] = $pdUserID;
            $planetDomainUser['user.lastname'] = $params['Registrant_LastName'];
            $planetDomainUser['user.firstname'] = $params['Registrant_FirstName'];

            if ($params['Registrant_OrganizationName'] != "") {
                $planetDomainUser['user.company'] = $params['Registrant_OrganizationName'];
                $planetDomainUser['user.type'] = 'COMPANY';
            }

            $planetDomainUser['user.address1'] = $params['Registrant_Address1'];

            if($params['Registrant_Address2'] != "") {
                $planetDomainUser['user.address2'] = $params['Registrant_Address2'];
            }

            $planetDomainUser['user.suburb'] = $params['Registrant_City'];
            $planetDomainUser['user.postcode'] = $params['Registrant_PostalCode'];
            $planetDomainUser['user.state'] = $params['Registrant_StateProv'];
            $planetDomainUser['user.country'] = $params['Registrant_Country'];
            $planetDomainUser['user.phone'] = $params['Registrant_Phone'];
            $planetDomainUser['user.email'] = $params['Registrant_EmailAddress'];

            $planetdomain = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

            $userUpdateResult = $planetdomain->updateUser($operation,$planetDomainUser);

            $userUpdateResponse = $this->processResponse($userUpdateResult);

            $this->logger->log(4, 'Planet Domain Returned: '.print_r($userUpdateResponse, true));

            if($userUpdateResponse["success"] == 'TRUE') {
                return $userUpdateResponse["success"];

            } else {
                return new NE_Error("Failed to update User Details", 1001);
            }

        } else {
            return new NE_Error("Failed to update User Details", 1001);
        }

        return new NE_Error("Failed to update User Details", 1001);

    }

    function getGeneralInfo($params) {

        // PlanetDomain returns lots of E_NOTICE
        error_reporting(E_ALL & ~E_NOTICE);

        $operation = "domain.info";
        $domain = strtolower($params['sld'].".".$params['tld']);
        $planetdomain = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

        $generalInfoResult = $planetdomain->domainInfo($operation,$domain);

        $generalInfoResponse = $this->processResponse($generalInfoResult);

        $this->logger->log(4, 'Planet Domain Result: '.print_r($generalInfoResponse, true));

        if($generalInfoResponse["success"] != 'TRUE') {
            return new NE_Error("Failed to get domain details", 1001);

        }

        $data = array();
        $data['expiration'] = $generalInfoResponse['domain.expirydate'];
        $data['domain'] = $generalInfoResponse['domain.name'];
        $data['id'] = $this->user->lang('Unknown');
        $data['registrationstatus'] = $generalInfoResponse['domain.status'];
        $data['purchasestatus'] = $generalInfoResponse['domain.status'];
        //$data['autorenew'] = $ret['isOrderSuspendedUponExpiry'] == 'false'? false : true;

        return $data;
    }

    function getNameServers($params){

        // PlanetDomain returns lots of E_NOTICE
        error_reporting(E_ALL & ~E_NOTICE);

        $operation = "domain.info";
        $domain = strtolower($params['sld'].".".$params['tld']);
        $planetdomain = new PlanetDomain($params['Admin Username'],
                                $params['Admin Password'],
                                $params['Reseller Id'],
                                $this->logger);

        $generalInfoResult = $planetdomain->domainInfo($operation,$domain);

        $generalInfoResponse = $this->processResponse($generalInfoResult);

        $this->logger->log(4, 'Planet Domain Result: '.print_r($generalInfoResponse, true));

        if($generalInfoResponse["success"] != 'TRUE'){
            return new NE_Error("Failed to get domain details", 1001);

        }

        $i = 0;
        $ns = array();
        $ns['hasDefault'] = 0;
        while (isset($generalInfoResponse['ns.name.'.$i])) {
            $ns[] = $generalInfoResponse['ns.name.'.$i];
            $i++;
        }
        return $ns;
    }

    
//     function setNameServers($params)
//     {
// 
//         $host = "https://www.planetdomain.com/servlet/TLDServlet";
// 
//         if ($params['Use testing server']) {
//             $host = "https://www.planetdomain.com/servlet/TLDServlet";
//         }
// 
//         $operation = "domain.update.ns";
//         $domain = strtolower($params['sld'].".".$params['tld']);
//         $planetdomain = new PlanetDomain($host,
//                                 $params['Admin Username'],
//                                 $params['Admin Password'],
//                                 $params['Reseller Id'],
//                                 $this->logger);
// 
//         $dnsData = array();
// 
//         $dnsData['domain.name'] = $domain;
// 
//         foreach ($params['ns'] as $key => $value) {
//             $intkey = (int) $key;
//             $intkey = $intkey - 1;
//             $dnsData['ns.name.'.$intkey] = $value;
//         }
// 
//         $this->logger->log(4, 'DNS SET Array : '.print_r($dnsData, true));
// 
//         $updateDNSResult = $planetdomain->updateDNS($operation,$domain);
// 
//         $updateDNSResponse = $this->processResponse($updateDNSResult);
// 
//         if($updateDNSResponse["success"] == 'TRUE')
//         {
//             return $updateDNSResponse["success"];
// 
//         }
// 
//         return new NE_Error("Failed to update DNS", 1001);
// 
//     }

    function string_ends_with($string, $ending) {
        $len = strlen($ending);
        $string_end = substr($string, strlen($string) - $len);
        return $string_end == $ending;
    }

    function processResponse($res){
        $responseArr = array();
        $fieldsArr = explode("\n",$res);

        for($i=0; $i < count($fieldsArr); $i++) {
            $fields = $fieldsArr[$i];
            $keyValueArr = explode("=",$fields);
            $key = trim($keyValueArr[0]);
            $value = trim($keyValueArr[1]);
            $responseArr[$key] = $value;
        }

        return $responseArr;
    }

    // @access private
    function _validatePhone($phone, $country){
        // strip all non numerical values
        $phone = preg_replace('/[^\d]/', '', $phone);

        $query = "SELECT phone_code FROM country WHERE iso=? AND phone_code != ''";
        $result = $this->db->query($query, $country);
        if (!$row = $result->fetch()) {
            return $phone;
        }

        // check if code is already there
        $code = $row['phone_code'];
        $phone = preg_replace("/^($code)(\\d+)/", '+\1.\2', $phone);
        if ($phone[0] == '+') {
            return $phone;
        }

        // if not, prepend it
        return "+$code.$phone";
    }

    function getNSIPByName($hostname) {

        $query = "SELECT ip FROM nameserver WHERE hostname=?";
        $result = $this->db->query($query, $hostname);
        return $result->fetch();
    }

    function getDefaultServerIP($domainname) {
        $query = "SELECT cd.value FROM domain_customdomainfields cd, domains d WHERE d.id = cd.userid AND d.DomainName =?";
        $result = $this->db->query($query, $domainname);
        return $result->fetch();
    }

    function disableRenewal($params){
    }

}

?>
