<?php

###############################################################################
# namecheap.php
#
# @author Anil Kumar <akumar@codepunch.com>
# @link   https://codepunch.com
#
############################################################################### 

namespace CodePunch\LU\Registrars;

use Exception;
use CodePunch\Base\Util as UTIL;

###############################################################################

class NameCheap extends RegistrarAPI {
	
	private $api_url_base  		= 'https://api.namecheap.com/xml.response';
	private $api_access_key		= null;
	private $api_access_user	= null;
	private $nc_user_name 		= null;
	private $contact_info 		= array();
	
	###########################################################################
	
	public function __construct($cm, $apikey, $apiuser, $username)
	{ 
		parent::__construct($cm);
		if(UTIL::starts_with($apikey, "sandbox::")) {
			$apikey = substr($apikey, 9);
			$this->use_sandbox(true);
		}
		$this->api_access_key = $apikey;
		$this->api_access_user = $apiuser;
		$this->nc_user_name = $username;
	}
	
	###########################################################################
	
	public static function getKeyNames()
	{
		return array('API Key', 'API User', 'Account User');
	}
	
	###########################################################################
	
	public function supported() {
		return array('domainlist', 'whois', 'availcheck', 'renew', 'pricing', 'balance', 'getcreatedata', 'register', 'getns', 'setns');
	}
	
	###########################################################################
	
	public function use_sandbox($flag)
	{
		if($flag === true)
			$this->api_url_base = 'https://api.sandbox.namecheap.com/xml.response';
		else
			$this->api_url_base = 'https://api.namecheap.com/xml.response';
		return true;
	}
	
	###########################################################################
	
	private function construct_url($command, $extraparams)
	{
		if(UTIL::is_cli()) {
			$ipaddress = file_get_contents("http://whatismyip.akamai.com/");
		}
		else
			$ipaddress = $_SERVER['SERVER_ADDR'];
		return $this->api_url_base . "?ApiUser={$this->api_access_user}&ApiKey={$this->api_access_key}&UserName={$this->nc_user_name}&ClientIp={$ipaddress}&Command={$command}&{$extraparams}";
	}
	
	###########################################################################

	private function get_contact_info($domain, $flatten=true)
	{
		$url = $this->construct_url("namecheap.domains.getContacts", "DomainName={$domain}");
		$contactinfo = UTIL::curl_get_url($url, 10);
		if($contactinfo !== false)
		{
			$contactinfo = $contactinfo['result'];
			$contactinfo = simplexml_load_string($contactinfo);
			$contactinfo = json_decode(json_encode($contactinfo), TRUE);
			if(isset($contactinfo['CommandResponse']['DomainContactsResult'])) {
				$contactinfo = $contactinfo['CommandResponse']['DomainContactsResult'];
				$contactinfo = UTIL::array_flatten($contactinfo);
				
				$fullname = "";
				if(isset($contactinfo['RegistrantFirstName']))
					$fullname = $contactinfo['RegistrantFirstName'];
				if(isset($contactinfo['RegistrantLastName']))
					$fullname .= " " . $contactinfo['RegistrantLastName'];
				$contactinfo['Registrant Name'] = $fullname;
				
				$unsetkeys = array('@attributesDomain', '@attributesdomainnameid', 'Registrant@attributesReadOnly', 'Tech@attributesReadOnly', 'Admin@attributesReadOnly', 'AuxBilling@attributesReadOnly', 'RegistrantStateProvinceChoice', 'TechStateProvinceChoice', 'AdminStateProvinceChoice', 'AuxBillingStateProvinceChoice');
				foreach($unsetkeys as $key)
					unset($contactinfo[$key]);
					
				foreach($contactinfo as $key => $value) {
					if(UTIL::starts_with($key, "WhoisGuard")) {
						if($key != 'WhoisguardExpiredDate' && $key != 'WhoisguardID' && $key != 'Whoisguard@attributesEnabled')
							unset($contactinfo[$key]);
					}
				}
					
				if($flatten) {
					$this->cleanup_keys($contactinfo);
					$contactinfo = UTIL::array_to_text($contactinfo);
				}
				return $contactinfo;
			}
		}
		return false;
	}
	
	###########################################################################
	
	private function cleanup_keys(&$info)
	{
		$xlate = array(
		'@attributesStatus' => 'Domain Status',
		'@attributesID' => 'Domain ID',
		'@attributesDomainName' => 'Domain',
		'@attributesOwnerName' => 'Registrant User Name',
		'@attributesIsOwner' => 'Is Owner',
		'@attributesIsPremium' => 'Is Premium',
		'DomainDetailsCreatedDate' => 'Creation Date',
		'DomainDetailsExpiredDate' => 'Expiry Date',
		'DomainDetailsNumYears' => 'Num Years',
		'Whoisguard@attributesEnabled' => 'Whois Guard',
		'WhoisguardID' => 'Whoisguard ID',
		'WhoisguardExpiredDate' => 'Whois Guard End Date',
		'PremiumDnsSubscriptionUseAutoRenew' => 'Premium DNS AutoRenew',
		'PremiumDnsSubscriptionSubscriptionId' => 'Premium DNS Subscription Id',
		'PremiumDnsSubscriptionCreatedDate' => 'Premium DNS Subscription Start Date',
		'PremiumDnsSubscriptionExpirationDate' => 'Premium DNS Subscription End Date',
		'PremiumDnsSubscriptionIsActive' => 'Premium DNS Subscription Active',
		'DnsDetails@attributesProviderType' => 'DNS Provider Type',
		'DnsDetails@attributesIsUsingOurDNS' => 'DNS Using Ours',
		'DnsDetails@attributesHostCount' => 'DNS Host Count',
		'DnsDetails@attributesEmailType' => 'DNS Email Type',
		'DnsDetails@attributesDynamicDNSStatus' => 'DNS Dynamic',
		'DnsDetails@attributesIsFailover' => 'DNA Failover',
		'DnsDetailsNameserver0' => 'Name Server 0',
		'DnsDetailsNameserver1' => 'Name Server 1',
		'DnsDetailsNameserver2' => 'Name Server 2',
		'DnsDetailsNameserver3' => 'Name Server 3',
		'DnsDetailsNameserver4' => 'Name Server 4',
		'DnsDetailsNameserver5' => 'Name Server 5',
		'DnsDetailsNameserver6' => 'Name Server 6',
		'Modificationrights@attributesAll' => 'Modification Rights',
		'RegistrantFirstName' => 'Registrant First Name',
		'RegistrantLastName' => 'Registrant Last Name',
		'AuxBillingEmailAddress' => 'Aux Billing Email',
		'RegistrantEmailAddress' => 'Registrant Email',
		'TechEmailAddress' => 'Tech Email',
		'AdminEmailAddress' => 'Admin Email',
		'RegistrantAddress1' => 'Registrant Address',
		'RegistrantAddress2' => 'Registrant Street',
		'RegistrantCity' => 'Registrant City',
		'RegistrantStateProvince' => 'Registrant State',
		'RegistrantPostalCode' => 'Registrant Postal Code',
		'RegistrantCountry' => 'Registrant Country',
		'RegistrantPhone' => 'Registrant Phone',
		'AdminAddress1' => 'Admin Address',
		'AdminAddress2' => 'Admin Street',
		'AdminCity' => 'Admin City',
		'AdminStateProvince' => 'Admin State',
		'AdminPostalCode' => 'Admin Postal Code',
		'AdminCountry' => 'Admin Country',
		'AdminPhone' => 'Admin Phone',
		'TechAddress1' => 'Tech Address',
		'TechAddress2' => 'Tech Street',
		'TechCity' => 'Tech City',
		'TechStateProvince' => 'Tech State',
		'TechPostalCode' => 'Tech Postal Code',
		'TechCountry' => 'Tech Country',
		'TechPhone' => 'Tech Phone',
		'AuxBillingAddress1' => 'Aux Billing Address',
		'AuxBillingAddress2' => 'Aux Billing Street',
		'AuxBillingCity' => 'Aux Billing City',
		'AuxBillingStateProvince' => 'Aux Billing State',
		'AuxBillingPostalCode' => 'Aux Billing Postal Code',
		'AuxBillingCountry' => 'Aux Billing Country',
		'AuxBillingPhone' => 'Aux Billing Phone',
		'TechFirstName' => 'Tech First Name',
		'TechLastName' => 'Tech Last Name',
		'AdminFirstName' => 'Admin First Name',
		'AdminLastName' => 'Admin Last Name',
		'AuxBillingFirstName' => 'Aux Billing First Name',
		'AuxBillingLastName' => 'Aux Billing Last Name',
		);
		UTIL::array_xlate_keys($info, $xlate);
		
		// Namecheap uses mm/dd/yyyy, let us convert the dates to yyyy-mm-dd
		// PHP's strtotime assumes mm/dd/yyyy when the separator is / 
		// and dd-mm-yyyy when the separator is -
		$datekeys = array('Expiry Date', 'Creation Date');
		foreach($datekeys as $dk) {
			if(isset($info[$dk])) {
				$thedate = $info[$dk];
				$info[$dk] = date('Y-m-d', strtotime($thedate));
			}
		}
	}
	
	###########################################################################
	
	public function whois($domain)
	{
		$responce = array('status'=>false,'error'=>'','data'=>'');
		try
		{
			if(stristr($domain, "xn--") === false)
				$domain = UTIL::idn_convert($domain);
			$url = $this->construct_url("namecheap.domains.getInfo", "DomainName={$domain}");
			$udata = UTIL::curl_get_url($url, 10);
			// curl_get_url will always return an array
			$whois = $udata['result'];
			if($whois != "") {
				$whoisdata = simplexml_load_string($whois);
				$whoisdata = json_decode(json_encode($whoisdata), TRUE);
				if($whoisdata !== false) {
					if(isset($whoisdata['Errors']['Error']))
						throw new Exception($whoisdata['Errors']['Error']);
					else {
						if(isset($whoisdata['CommandResponse']['DomainGetInfoResult'])) {
							$whoisdata = $whoisdata['CommandResponse']['DomainGetInfoResult'];
							$whoisdata = UTIL::array_flatten($whoisdata);
							
							foreach($whoisdata as $key => $value) {
								if(UTIL::starts_with($key, "WhoisguardEmailDetails")) 
									unset($whoisdata[$key]);
							}
				
							$whoisdata['Registrar'] = "NameCheap";
							$this->cleanup_keys($whoisdata);
							$whoisdata = UTIL::array_to_text($whoisdata);
							
							$contacts = $this->get_contact_info($domain);
							
							$whoisdata .= "\n";
							$whoisdata .= $contacts;
							$responce['data'] = $whoisdata;
							$responce['status'] = true;
						}
					}
				}
			}
			else
				throw new Exception("Unable to connect to NameCheap API server");
		}
		catch (Exception $e) {
			$responce['error'] = $e->getMessage();
		}
		return $responce;
	}
	
	###########################################################################

	public function isWorking()
	{
		$url = $this->construct_url("namecheap.domains.getList", "Page=1&PageSize=10");
		$info = UTIL::curl_get_url($url, 10);
		if(isset($info['status']) && $info['status'] == 200) {
			if($info['result'] != "") {
				$info = $info['result'];
				$info = simplexml_load_string($info);
				$domaininfo = json_decode(json_encode($info), TRUE);
				if(isset($domaininfo['@attributes']['Status']) && $domaininfo['@attributes']['Status'] == "OK")
					return true;
				else
					if(isset($domaininfo['Errors']['Error']))
						return $domaininfo['Errors']['Error'];
			}
		}
		return "Unable to connect";
	}

	###########################################################################
	
	public function domainlist(callable $callback=null)
	{
		$domains = array();
		$page = 1;
		$pagesize = 100;
		$added = 1;
		while($added) {
			$thisdata = array();
			$added = 0;
			$url = $this->construct_url("namecheap.domains.getList", "Page={$page}&PageSize={$pagesize}");
			$info = UTIL::curl_get_url($url, 10);
			if($info['result'] != "")
			{
				$info = $info['result'];
				$info = simplexml_load_string($info);
				$domaininfo = json_decode(json_encode($info), TRUE);
				if(isset($domaininfo['Errors']['Error']))
					throw new Exception($domaininfo['Errors']['Error']);
				else {
					if(isset($domaininfo['CommandResponse']['DomainGetListResult']['Domain'])) {
						$domaininfo = $domaininfo['CommandResponse']['DomainGetListResult']['Domain'];
						if(is_array($domaininfo)) {
							foreach($domaininfo as $di) {
								if(isset($di['@attributes']['Name'])) {
									$thisdata[] = $di['@attributes']['Name'];
									$added++;
								}
								else if(isset($di['Name']) && count($domaininfo) == 1) {
									$thisdata[] = $di['Name'];
									$added++;
								}
							}
						}
					}
				}
			}
			else 
				throw new Exception("Unable to connect to NameCheap API server");
			$page++;
			
			if($callback != null && $added) {
				$status = call_user_func($callback, "", count($domains), $thisdata);
				if($status == self::REGAPI_STOP)
					break;
			}
			if(count($thisdata))
				$domains = array_merge($domains, $thisdata);
		}

		return $domains;
	}
	
	###########################################################################
	/*
	Returns an array of arrays containg entries for each domain
	[Domain] => abcd.com
	[Available] => false
	[ErrorNo] => 0
	[Description] =>
	[IsPremiumName] => false
	[PremiumRegistrationPrice] => 0
	[PremiumRenewalPrice] => 0
	[PremiumRestorePrice] => 0
	[PremiumTransferPrice] => 0
	[IcannFee] => 0
	[EapFee] => 0.0
	*/
	
	public function availcheck($domainlist) {
		$domaindata = array();
		$dl = $domainlist;
		if(!is_array($domainlist))
			$domainlist = explode(",", $domainlist);
		foreach($domainlist as &$d) {
			$d = trim($d);
			if(stristr($d, "xn--") === false)
				$d = UTIL::idn_convert($d);
		}
		$dl = implode(",", $domainlist);
		$url = $this->construct_url("namecheap.domains.check", "DomainList={$dl}");
		$info = UTIL::curl_get_url($url, 10);
		if($info['result'] != "") {
			$info = $info['result'];
			$info = simplexml_load_string($info);
			$domaininfo = json_decode(json_encode($info), TRUE);
			if(isset($domaininfo['Errors']['Error']))
				throw new Exception($domaininfo['Errors']['Error']);
			if(isset($domaininfo['CommandResponse']['DomainCheckResult'])) {
				$domaininfo = $domaininfo['CommandResponse']['DomainCheckResult'];
				// Convert to an array if there is only a single entry.
				if(isset($domaininfo['@attributes']))
					$domaininfo = array($domaininfo);
				foreach($domaininfo as $di) {
					$domaindata[] = $di['@attributes'];
				}
				foreach($domaindata as &$d) 
					$this->cleanup_action_data($d);
			}
		}
		else 
			throw new Exception("Unable to connect to NameCheap API server");
		return $domaindata;
	}
	
	###########################################################################
	/*
	[Currency] => USD
    [AvailableBalance] => 8498.27
    [AccountBalance] => 8498.27
    [EarnedAmount] => 0.00
    [WithdrawableAmount] => 0.00
    [FundsRequiredForAutoRenew] => 0.00
	*/
	
	public function balance() {
		$url = $this->construct_url("namecheap.users.getBalances", "");
		$info = UTIL::curl_get_url($url, 10);
		if($info['result'] != "") {
			$info = $info['result'];
			$info = simplexml_load_string($info);
			$domaininfo = json_decode(json_encode($info), TRUE);
			if(isset($domaininfo['Errors']['Error']))
				throw new Exception($domaininfo['Errors']['Error']);
			if(isset($domaininfo['CommandResponse']['UserGetBalancesResult'])) {
				$domaininfo = $domaininfo['CommandResponse']['UserGetBalancesResult'];
				if(isset($domaininfo['@attributes'])) {
					$domaininfo = $domaininfo['@attributes'];
					$this->cleanup_action_data($domaininfo);
					return $domaininfo;
				}
			}
			throw new Exception("Unknown command response from NameCheap API server");
		}
		else 
			throw new Exception("Unable to connect to NameCheap API server");
	}
	
	###########################################################################
	/*
	Retuns an array of arrays with pricing data in the following format for durations 1-10
	[Duration] => 1
	[DurationType] => YEAR
	[Price] => 27.98
	[PricingType] => MULTIPLE
	[AdditionalCost] => 0.18
	[RegularPrice] => 27.98
	[RegularPriceType] => MULTIPLE
	[RegularAdditionalCost] => 0.18
	[RegularAdditionalCostType] => MULTIPLE
	[YourPrice] => 27.98
	[YourPriceType] => MULTIPLE
	[YourAdditonalCost] => 0.18
	[YourAdditonalCostType] => MULTIPLE
	[PromotionPrice] => 0.0
	[Currency] => USD
	*/
	
	public function pricing($requestdata) { 
		$producttype = "domain";
		$action = $requestdata['action'];
		$productname = $requestdata['tld'];
		if(stristr($productname, "xn--") === false)
			$productname = UTIL::idn_convert($productname);
		$category = "domains";
		$promocode = $requestdata['promocode'];
		if($productname == "")
			throw new Exception("Unknown product name.");
		$url = $this->construct_url("namecheap.users.getPricing", "ProductType={$producttype}&ActionName={$action}&ProductName={$productname}&ProductCategory={$category}&PromotionCode={$promocode}");
		$info = UTIL::curl_get_url($url, 10);
		if($info['result'] != "") {
			$info = $info['result'];
			$info = simplexml_load_string($info);
			$domaininfo = json_decode(json_encode($info), TRUE);
			if(isset($domaininfo['Errors']['Error']))
				throw new Exception($domaininfo['Errors']['Error']);
			if(isset($domaininfo['CommandResponse']['UserGetPricingResult'])) {
				$domaininfo = $domaininfo['CommandResponse']['UserGetPricingResult'];
				UTIL::cli_print($domaininfo);
				if(isset($domaininfo['ProductType']['ProductCategory']['Product']['Price'])) {
					$tld = $domaininfo['ProductType']['ProductCategory']['Product']['@attributes']['Name'];
					$domaininfo = $domaininfo['ProductType']['ProductCategory']['Product']['Price'];
					$dd = array();
					foreach($domaininfo as $di) {
						if(isset($di['@attributes'])) {
							$di['@attributes']['TLD'] = $tld;
							$dd[] = $di['@attributes'];
						}
					}
					$years = array();
					foreach($dd as $key => $row)
						$years[$key] = $row['Duration'];
					array_multisort($years, SORT_ASC, $dd);
					foreach($dd as &$d) {
						$this->cleanup_action_data($d);
						if($d['actual_price_type'] == "MULTIPLE")
							$d['actual_total_price'] = floatval($d['actual_price'])*intval($d['duration']);
						else
							$d['actual_total_price'] = $d['actual_price'];
						if(isset($d['actual_additional_cost'])) {
							if($d['actual_additional_cost_type'] == "MULTIPLE")
								$d['actual_additional_total_cost'] = floatval($d['actual_additional_cost'])*intval($d['duration']);
							else
								$d['actual_additional_total_cost'] = $d['actual_additional_cost'];
							$d['actual_total_cost'] = round($d['actual_total_price']+$d['actual_additional_total_cost'], 2);
						}
						else
							$d['actual_total_cost'] = round($d['actual_total_price'], 2);
					}
					return $dd;
				}
			}
			throw new Exception("Unknown command response from NameCheap API server");
		}
		else 
			throw new Exception("Unable to connect to NameCheap API server");
	}
	
	###########################################################################
	/*
	Returns an array with data like the following
	[DomainName] => nctb-toolpad.cc
    [DomainID] => 610215
    [Renew] => true
    [OrderID] => 2470649
    [TransactionID] => 6385725
    [ChargedAmount] => 10.2500
    [ExpiryDate] => 2026-08-06
	*/
	
	public function renew($requestdata) { 
		
		if(stristr($requestdata['domain'], "xn--") === false)
			$requestdata['domain'] = UTIL::idn_convert($requestdata['domain']);
		$url = $this->construct_url("namecheap.domains.renew", "DomainName=" . $requestdata['domain'] . "&Years=" . $requestdata['years'] . "&PromotionCode=" . $requestdata['promocode']);
		$info = UTIL::curl_get_url($url, 10);
		if($info['result'] != "") {
			$info = $info['result'];
			$info = simplexml_load_string($info);
			$domaininfo = json_decode(json_encode($info), TRUE);
			if(isset($domaininfo['Errors']['Error']))
				throw new Exception($domaininfo['Errors']['Error']);
			if(isset($domaininfo['CommandResponse']['DomainRenewResult'])) {
				$domaininfo = $domaininfo['CommandResponse']['DomainRenewResult'];
				if(isset($domaininfo['@attributes'])) {
					$dd = $domaininfo['@attributes'];
					if(isset($domaininfo['DomainDetails']['ExpiredDate'])) {
						$thedate = $domaininfo['DomainDetails']['ExpiredDate'];
						$dd['ExpiryDate'] = date('Y-m-d', strtotime($thedate));
					}
					$this->cleanup_action_data($dd);
					return $dd;
				}
			}
			else
				throw new Exception("Unknown command response from NameCheap API server");
		}
		else 
			throw new Exception("Unable to connect to NameCheap API server");
	}
	
	###########################################################################

	public function getns($domain)
	{
		$auth = $this->getConnectionManager()->getAuthentication();
		$db = $auth->getDatabase();
		$di  = UTIL::clean_domain_name($domain, $db->getDomainSuffixList());
		if($di['tld'] && $di['domain']) {
			$di['sld'] = str_replace("." . $di['tld'], "", $di['domain']);
			$di['sld'] = UTIL::idn_convert($di['sld']);
			$di['tld'] = UTIL::idn_convert($di['tld']);
			$url = $this->construct_url("namecheap.domains.dns.getList", "SLD=" . $di['sld'] . "&TLD=" . $di['tld']);
			$nsinfo = UTIL::curl_get_url($url, 10);
			if($nsinfo !== false) {
				$nsinfo = $nsinfo['result'];
				$nsinfo = simplexml_load_string($nsinfo);
				$nsinfo = json_decode(json_encode($nsinfo), TRUE);
				if(isset($nsinfo['Errors']['Error']))
					throw new Exception($nsinfo['Errors']['Error']);
				if(isset($nsinfo['CommandResponse']['DomainDNSGetListResult'])) {
					$nsinfo = $nsinfo['CommandResponse']['DomainDNSGetListResult'];
					if(isset($nsinfo['Nameserver']))
						return $nsinfo['Nameserver'];
				}
			}
			throw new Exception("Unknown command response from NameCheap API server");
		}
		else
			throw new Exception("Unable to connect to NameCheap API server");
	}
	
	###########################################################################

	public function setns($requestdata)
	{
		$domain = $requestdata['domain'];
		$ns = $requestdata['ns'];
		$auth = $this->getConnectionManager()->getAuthentication();
		$db = $auth->getDatabase();
		$di  = UTIL::clean_domain_name($domain, $db->getDomainSuffixList());
		if($di['tld'] && $di['domain']) {
			$di['sld'] = str_replace("." . $di['tld'], "", $di['domain']);
			$di['sld'] = UTIL::idn_convert($di['sld']);
			$di['tld'] = UTIL::idn_convert($di['tld']);
			$url = $this->construct_url("namecheap.domains.dns.setCustom", "SLD=" . $di['sld'] . "&TLD=" . $di['tld'] . "&Nameservers=" . urlencode($ns));
			$nsinfo = UTIL::curl_get_url($url, 10);
			if($nsinfo !== false) {
				$nsinfo = $nsinfo['result'];
				$nsinfo = simplexml_load_string($nsinfo);
				$nsinfo = json_decode(json_encode($nsinfo), TRUE);
				if(isset($nsinfo['Errors']['Error']))
					throw new Exception($nsinfo['Errors']['Error']);
				if(isset($nsinfo['CommandResponse']['DomainDNSSetCustomResult'])) {
					$nsinfo = $nsinfo['CommandResponse']['DomainDNSSetCustomResult'];
					if(isset($nsinfo['@attributes'])) {
						$ddi = $nsinfo['@attributes'];
						$this->cleanup_action_data($ddi);
						return $ddi;
					}
				}
			}
			throw new Exception("Unknown command response from NameCheap API server");
		}
		else
			throw new Exception("Unable to connect to NameCheap API server");
	}
	
	###########################################################################
	
	public function getcreatedata($sampledomain) {
		if(stristr($sampledomain, "xn--") === false)
			$sampledomain = UTIL::idn_convert($sampledomain);
		$di = $this->get_contact_info($sampledomain, false);
		$ns = $this->getns($sampledomain);
		if(is_array($ns)) {
			$di['Nameservers'] = implode(",", $ns);
		}
		$di['DomainName'] = $sampledomain;
		return $di;
	}
	
	###########################################################################
	
	public function register($requestdata) { 
		$sampledomain = isset($requestdata['copyfrom']) ? $requestdata['copyfrom'] : "";
		if($sampledomain != "") {
			$di = $this->getcreatedata($sampledomain);
		}
		else {
			$di = $requestdata['data'];
		}
		unset($di['Registrant Name']);
		$di['DomainName'] = $requestdata['domain'];
		$di['PromotionCode'] = $requestdata['promocode'];
		$di['Years'] = $requestdata['years'];
		if(stristr($di['DomainName'], "xn--") === false)
			$di['DomainName'] = UTIL::idn_convert($di['DomainName']);
		$udata = "";
		foreach($di as $k=>$v) {
			$udata .= "&" . $k . "=" . urlencode($v);
		}
		$udata = trim($udata, "&");
		
		$url = $this->construct_url("namecheap.domains.create", $udata);
		$info = UTIL::curl_get_url($url, 20);
		if($info['result'] != "") {
			$info = $info['result'];
			$info = simplexml_load_string($info);
			$domaininfo = json_decode(json_encode($info), TRUE);
			if(isset($domaininfo['Errors']['Error']))
				throw new Exception($domaininfo['Errors']['Error']);
			if(isset($domaininfo['CommandResponse']['DomainCreateResult'])) {
				$domaininfo = $domaininfo['CommandResponse']['DomainCreateResult'];
				if(isset($domaininfo['@attributes'])) {
					$ddi = $domaininfo['@attributes'];
					$this->cleanup_action_data($ddi);
					return $ddi;
				}
			}
			else
				throw new Exception("Unknown command response from NameCheap API server");
		}
		else 
			throw new Exception("Unable to connect to NameCheap API server");
	}
	
	###########################################################################
	
	private function cleanup_action_data(&$info) {
		$xlate = array(
			'DomainName' => 'domain',
			'Domain' => 'domain',
			'DomainID' => 'domain_id',
			'Renew' => 'renew_status',
			'OrderID' => 'order_id',
			'TransactionID' => 'transaction_id',
			'ChargedAmount' => 'charged_amount',
			'ExpiryDate' => 'new_expiry_date',
			
			'Duration' => 'duration',
            'DurationType' => 'duration_type',
            'Price' => 'total_price',
            'PricingType' => 'pricing-type',
            'AdditionalCost' => 'additional_price',
            'RegularPrice' => 'regular_price',
            'RegularPriceType' => 'regular_price_type',
            'RegularAdditionalCost' => 'regular_additional_cost',
            'RegularAdditionalCostType' => 'regular_additional_cost_type',
            'YourPrice' => 'actual_price',
            'YourPriceType' => 'actual_price_type',
            'YourAdditonalCost' => 'actual_additional_cost',
            'YourAdditonalCostType' => 'actual_additional_cost_type',
            'PromotionPrice' => 'promotion_price',
            'Currency' => 'currency',
            'TLD' => 'tld',
			
			'Available' => 'available',
            'ErrorNo' => 'error_no',
            'Description' => 'description',
            'IsPremiumName' => 'is_premium_name',
            'PremiumRegistrationPrice' => 'premium_registration_price',
            'PremiumRenewalPrice' => 'premium_renewal_price',
            'PremiumRestorePrice' => 'premium_restore_price',
            'PremiumTransferPrice' => 'premium_transfer_price',
            'IcannFee' => 'icann_fee',
            'EapFee' => 'eap_fee',
			
			'AvailableBalance' => 'available_balance',
			'AccountBalance' => 'account_balance',
			'EarnedAmount' => 'earned_amount',
			'WithdrawableAmount' => 'withdrawable_amount',
			'FundsRequiredForAutoRenew' => 'funds_required_for_auto_renew',
			
			'Registered' => 'registered',
			'Updated' => 'updated',
            'ChargedAmount' => 'charged_amount',
            'WhoisguardEnable' => 'whoisguard_enable',
            'FreePositiveSSL' => 'free_positive_ssl',
            'NonRealTimeDomain' => 'non_real_time_domain'
		);
		UTIL::array_xlate_keys($info, $xlate);
	}
	
	
}

###############################################################################
