<?php

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

namespace CodePunch\Whois;

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

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

class NameCheap {
	
	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();
	private $notfound_token 	= "Domain is invalid";
	
	public static $whois_server	= "NameCheap";
	
	###########################################################################
	
	public function __construct($apiuser, $apikey, $username)
	{ 
		$this->api_access_key = $apikey;
		$this->api_access_user = $apiuser;
		$this->nc_user_name = $username;
	}
	
	###########################################################################
	
	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)
	{
		$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)
	{
		$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]);
					}
				}
					
				$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',
		'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);
	}
	
	###########################################################################
	
	public function whois($domain, $fallback=false)
	{
		try
		{
			$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;
							return $whoisdata;
						}
					}
				}
			}
			else
				throw new Exception("Unable to connect to NameCheap API server");
		}
		catch (Exception $e) {
			if($fallback) 
				return WHOIS::redirect_to_port_43_whois($domain, self::$whois_server, $this->notfound_token, $e->getMessage());
		}
		return "";
	}
	
	###########################################################################
	
	public function domainlist()
	{
		$domains = array();
		$page = 1;
		$pagesize = 100;
		$added = 1;
		while($added) {
			$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'])) {
									$domains[] = $di['@attributes']['Name'];
									$added++;
								}
							}
						}
					}
				}
			}
			else 
				throw new Exception("Unable to connect to NameCheap API server");
			$page++;
		}

		return $domains;
	}
}

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

?>