diff --git a/README.md b/README.md
index 9d0d5eb..75804c7 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,17 @@
-# registrar-whmcs-epp-verisign
-VeriSign EPP Module for Namingo Registrar
+# VeriSign EPP Module for Namingo Registrar Platform
+
+This is an **EPP Registrar Module** specifically designed for the Namingo Registrar platform’s WHMCS edition.
+
+> ⚠️ **Note**: This module is exclusive to the Namingo Registrar platform’s WHMCS edition and is not compatible with standard WHMCS installations.
+
+## Compatibility
+
+This module supports **all gTLDs** that use the VeriSign platform.
+
+> **Note**: For Generic EPP support, please use our standard [Registrar-WHMCS-EPP-RFC module](https://github.com/getnamingo/registrar-whmcs-epp-rfc) for full compatibility.
+
+> **Note**: For ccTLD support, please use our standard [WHMCS-EPP-RFC module](https://github.com/getpinga/whmcs-epp-rfc) for full compatibility.
+
+## Installation instructions
+
+This module is exclusively for use as part of the **Namingo Registrar Platform (WHMCS Edition)**. For complete installation instructions, please visit the [Installation Guide](https://namingo.org/registrar).
\ No newline at end of file
diff --git a/logo.gif b/logo.gif
new file mode 100644
index 0000000..1392b75
Binary files /dev/null and b/logo.gif differ
diff --git a/manageDNSSECDSRecords.tpl b/manageDNSSECDSRecords.tpl
new file mode 100644
index 0000000..95f66f4
--- /dev/null
+++ b/manageDNSSECDSRecords.tpl
@@ -0,0 +1,124 @@
+
+
+
Manage DNSSEC DS Records
+
+{if $error}
+
+ {$error}
+
+{else}
+ {if $DSRecords eq 'YES'}
+ {foreach $DSRecordslist as $item}
+
+ {/foreach}
+ {else}
+
+ {$DSRecords}
+
+ {/if}
+{/if}
+
+
+
+
+
+
+
+
+
+
+
+
+ Create a DS Record
+
+
+
+
+
+
+
+
+ Create DS Record
+
+
+
+
+
+
\ No newline at end of file
diff --git a/verisign.php b/verisign.php
new file mode 100644
index 0000000..da67c1d
--- /dev/null
+++ b/verisign.php
@@ -0,0 +1,2509 @@
+ 'EPP Registry',
+ 'APIVersion' => '1.1',
+ );
+}
+
+function _verisign_error_handler($errno, $errstr, $errfile, $errline)
+{
+ if (!preg_match("/epp/i", $errfile)) {
+ return true;
+ }
+
+ _verisign_log("Error $errno:", "$errstr on line $errline in file $errfile");
+}
+
+set_error_handler('_verisign_error_handler');
+_verisign_log('================= ' . date("Y-m-d H:i:s") . ' =================');
+
+function verisign_getConfigArray($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+
+ $configarray = array(
+ 'FriendlyName' => array(
+ 'Type' => 'System',
+ 'Value' => 'VeriSign EPP',
+ ),
+ 'Description' => array(
+ 'Type' => 'System',
+ 'Value' => 'This module supports all gTLDs that use the VeriSign platform.',
+ ),
+ 'host' => array(
+ 'FriendlyName' => 'EPP Server',
+ 'Type' => 'text',
+ 'Size' => '32',
+ 'Description' => 'EPP Server Host.'
+ ),
+ 'port' => array(
+ 'FriendlyName' => 'Server Port',
+ 'Type' => 'text',
+ 'Size' => '4',
+ 'Default' => '700',
+ 'Description' => 'System port number 700 has been assigned by the IANA for mapping EPP onto TCP.'
+ ),
+ 'tls_version' => array(
+ 'FriendlyName' => 'Use TLS v1.3',
+ 'Type' => 'yesno',
+ 'Description' => 'Use more secure TLS v1.3 if the registry supports it.'
+ ),
+ 'verify_peer' => array(
+ 'FriendlyName' => 'Verify Peer',
+ 'Type' => 'yesno',
+ 'Description' => 'Require verification of SSL certificate used.'
+ ),
+ 'cafile' => array(
+ 'FriendlyName' => 'CA File',
+ 'Type' => 'text',
+ 'Default' => '',
+ 'Description' => 'Certificate Authority file which should be used with the verify_peer context option to authenticate the identity of the remote peer.'
+ ),
+ 'local_cert' => array(
+ 'FriendlyName' => 'Certificate',
+ 'Type' => 'text',
+ 'Default' => 'cert.pem',
+ 'Description' => 'Local certificate file. It must be a PEM encoded file.'
+ ),
+ 'local_pk' => array(
+ 'FriendlyName' => 'Private Key',
+ 'Type' => 'text',
+ 'Default' => 'key.pem',
+ 'Description' => 'Private Key.'
+ ),
+ 'passphrase' => array(
+ 'FriendlyName' => 'Pass Phrase',
+ 'Type' => 'password',
+ 'Size' => '32',
+ 'Description' => 'Enter pass phrase with which your certificate file was encoded.'
+ ),
+ 'clid' => array(
+ 'FriendlyName' => 'Client ID',
+ 'Type' => 'text',
+ 'Size' => '20',
+ 'Description' => 'Client identifier.'
+ ),
+ 'pw' => array(
+ 'FriendlyName' => 'Password',
+ 'Type' => 'password',
+ 'Size' => '20',
+ 'Description' => "Client's plain text password."
+ ),
+ 'registrarprefix' => array(
+ 'FriendlyName' => 'Registrar Prefix',
+ 'Type' => 'text',
+ 'Size' => '4',
+ 'Description' => 'Registry assigns each registrar a unique prefix with which that registrar must create contact IDs.'
+ )
+ );
+ return $configarray;
+}
+
+function _verisign_startEppClient($params = array())
+{
+ $s = new verisign_epp_client($params);
+ $s->login($params['clid'], $params['pw'], $params['registrarprefix']);
+ return $s;
+}
+
+function verisign_RegisterDomain($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-check-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->chkData;
+ $reason = (string)$r->cd[0]->reason;
+ if (!$reason) {
+ $reason = 'Domain is not available';
+ }
+
+ if (0 == (int)$r->cd[0]->name->attributes()->avail) {
+ throw new exception($r->cd[0]->name . ' ' . $reason);
+ }
+
+ $contacts = array();
+ foreach(array(
+ 'registrant',
+ 'admin',
+ 'tech',
+ 'billing'
+ ) as $i => $contactType) {
+ // contact:create
+ $from = $to = array();
+ $from[] = '/{{ id }}/';
+ $to[] = strtoupper($s->generateRandomString());
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['firstname'] . ' ' . $params['lastname']);
+ $from[] = '/{{ org }}/';
+ $to[] = htmlspecialchars($params['companyname']);
+ $from[] = '/{{ street1 }}/';
+ $to[] = htmlspecialchars($params['address1']);
+ $from[] = '/{{ street2 }}/';
+ $to[] = htmlspecialchars($params['address2']);
+ $from[] = '/{{ street3 }}/';
+ $street3 = (isset($params['address3']) ? $params['address3'] : '');
+ $to[] = htmlspecialchars($street3);
+ $from[] = '/{{ city }}/';
+ $to[] = htmlspecialchars($params['city']);
+ $from[] = '/{{ state }}/';
+ $to[] = htmlspecialchars($params['state']);
+ $from[] = '/{{ postcode }}/';
+ $to[] = htmlspecialchars($params['postcode']);
+ $from[] = '/{{ country }}/';
+ $to[] = htmlspecialchars($params['country']);
+ $from[] = '/{{ phonenumber }}/';
+ $to[] = htmlspecialchars($params['fullphonenumber']);
+ $from[] = '/{{ email }}/';
+ $to[] = htmlspecialchars($params['email']);
+ $from[] = '/{{ authInfo }}/';
+ $to[] = htmlspecialchars($s->generateObjectPW());
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-contact-create-' . $clTRID);
+ $from[] = "/<\w+:\w+>\s*<\/\w+:\w+>\s+/ims";
+ $to[] = '';
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ id }}
+
+ {{ name }}
+ {{ org }}
+
+ {{ street1 }}
+ {{ street2 }}
+ {{ street3 }}
+ {{ city }}
+ {{ state }}
+ {{ postcode }}
+ {{ country }}
+
+
+ {{ phonenumber }}
+
+ {{ email }}
+
+ {{ authInfo }}
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:contact-1.0')->creData;
+ $contacts[$i + 1] = $r->id;
+ }
+
+ foreach(array(
+ 'ns1',
+ 'ns2',
+ 'ns3',
+ 'ns4',
+ 'ns5'
+ ) as $ns) {
+ if (empty($params["{$ns}"])) {
+ continue;
+ }
+
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params["{$ns}"]);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-host-check-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:host-1.0')->chkData;
+
+ if (0 == (int)$r->cd[0]->name->attributes()->avail) {
+ continue;
+ }
+
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params["{$ns}"]);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-host-create-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+}
+
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ period }}/';
+ $to[] = htmlspecialchars($params['regperiod']);
+ $from[] = '/{{ ns1 }}/';
+ $to[] = htmlspecialchars($params['ns1']);
+ $from[] = '/{{ ns2 }}/';
+ $to[] = htmlspecialchars($params['ns2']);
+ $from[] = '/{{ ns3 }}/';
+ $to[] = htmlspecialchars($params['ns3']);
+ $from[] = '/{{ ns4 }}/';
+ $to[] = htmlspecialchars($params['ns4']);
+ $from[] = '/{{ ns5 }}/';
+ $to[] = htmlspecialchars($params['ns5']);
+ $from[] = '/{{ cID_1 }}/';
+ $to[] = htmlspecialchars($contacts[1]);
+ $from[] = '/{{ cID_2 }}/';
+ $to[] = htmlspecialchars($contacts[2]);
+ $from[] = '/{{ cID_3 }}/';
+ $to[] = htmlspecialchars($contacts[3]);
+ $from[] = '/{{ cID_4 }}/';
+ $to[] = htmlspecialchars($contacts[4]);
+ $from[] = '/{{ authInfo }}/';
+ $to[] = htmlspecialchars($s->generateObjectPW());
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-create-' . $clTRID);
+ $from[] = "/<\w+:\w+>\s*<\/\w+:\w+>\s+/ims";
+ $to[] = '';
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+ {{ period }}
+
+ {{ ns1 }}
+ {{ ns2 }}
+ {{ ns3 }}
+ {{ ns4 }}
+ {{ ns5 }}
+
+ {{ cID_1 }}
+ {{ cID_2 }}
+ {{ cID_3 }}
+ {{ cID_4 }}
+
+ {{ authInfo }}
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+
+ // Check if the required module 'whmcs_registrar' is active
+ if (!Capsule::table('tbladdonmodules')->where('module', 'whmcs_registrar')->exists()) {
+ // Log an error if the module is not active
+ _verisign_log('Error: Required module is not active.');
+ }
+
+ // Insert contacts and get their IDs
+ $contactIds = insertContacts($params, $contacts);
+
+ // Insert domain
+ insertDomain($params, $contactIds);
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_RenewDomain($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $expDate = (string)$r->exDate;
+ $expDate = preg_replace("/^(\d+\-\d+\-\d+)\D.*$/", "$1", $expDate);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ regperiod }}/';
+ $to[] = htmlspecialchars($params['regperiod']);
+ $from[] = '/{{ expDate }}/';
+ $to[] = htmlspecialchars($expDate);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-renew-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+ {{ expDate }}
+ {{ regperiod }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_TransferDomain($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ years }}/';
+ $to[] = htmlspecialchars($params['regperiod']);
+ $from[] = '/{{ authInfo_pw }}/';
+ $to[] = htmlspecialchars($params['transfersecret']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-transfer-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+ {{ years }}
+
+ {{ authInfo_pw }}
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->trnData;
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_GetNameservers($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $i = 0;
+ foreach($r->ns->hostObj as $ns) {
+ $i++;
+ $return["ns{$i}"] = (string)$ns;
+ }
+
+ $namingoDomainId = getNamingoDomainId($params['domainid']);
+
+ $status = array();
+ Capsule::table('namingo_domain_status')->where('domain_id', '=', $namingoDomainId)->delete();
+ foreach($r->status as $e) {
+ $st = (string)$e->attributes()->s;
+ if ($st == 'pendingDelete') {
+ $updatedDomainStatus = Capsule::table('tbldomains')->where('id', $params['domainid'])->update(['status' => 'Cancelled']);
+ }
+
+ Capsule::table('namingo_domain_status')->insert(['domain_id' => $namingoDomainId, 'status' => $st]);
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_SaveNameservers($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $add = $rem = array();
+ $i = 0;
+ foreach($r->ns->hostObj as $ns) {
+ $i++;
+ $ns = (string)$ns;
+ if (!$ns) {
+ continue;
+ }
+
+ $rem["ns{$i}"] = $ns;
+ }
+
+ foreach($params as $k => $v) {
+ if (!$v) {
+ continue;
+ }
+
+ if (!preg_match("/^ns\d$/i", $k)) {
+ continue;
+ }
+
+ if ($k0 = array_search($v, $rem)) {
+ unset($rem[$k0]);
+ }
+ else {
+ $add[$k] = $v;
+ }
+ }
+
+ if (!empty($add) || !empty($rem)) {
+ $from = $to = array();
+ $text = '';
+ foreach($add as $k => $v) {
+ $text.= '' . $v . ' ' . "\n";
+ }
+
+ $from[] = '/{{ add }}/';
+ $to[] = (empty($text) ? '' : "\n{$text} \n");
+ $text = '';
+ foreach($rem as $k => $v) {
+ $text.= '' . $v . ' ' . "\n";
+ }
+
+ $from[] = '/{{ rem }}/';
+ $to[] = (empty($text) ? '' : "\n{$text} \n");
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+ {{ add }}
+ {{ rem }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_GetRegistrarLock($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = 'unlocked';
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ foreach($r->status as $e) {
+ $attr = $e->attributes();
+ if (preg_match("/clientTransferProhibited/i", $attr['s'])) {
+ $return = 'locked';
+ }
+ }
+ }
+
+ catch(exception $e) {
+ $return = 'locked';
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_SaveRegistrarLock($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $status = array();
+ foreach($r->status as $e) {
+ $st = (string)$e->attributes()->s;
+ if (!preg_match("/^client.+Prohibited$/i", $st)) {
+ continue;
+ }
+
+ $status[$st] = true;
+ }
+
+ $rem = $add = array();
+ foreach(array(
+ 'clientDeleteProhibited',
+ 'clientTransferProhibited'
+ ) as $st) {
+ if ($params["lockenabled"] == 'locked') {
+ if (!isset($status[$st])) {
+ $add[] = $st;
+ }
+ }
+ else {
+ if (isset($status[$st])) {
+ $rem[] = $st;
+ }
+ }
+ }
+
+ if (!empty($add) || !empty($rem)) {
+ $text = '';
+ foreach($add as $st) {
+ $text.= ' ' . "\n";
+ }
+
+ $from[] = '/{{ add }}/';
+ $to[] = (empty($text) ? '' : "\n{$text} \n");
+ $text = '';
+ foreach($rem as $st) {
+ $text.= ' ' . "\n";
+ }
+
+ $from[] = '/{{ rem }}/';
+ $to[] = (empty($text) ? '' : "\n{$text} \n");
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+ {{ rem }}
+ {{ add }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_GetContactDetails($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $dcontact = array();
+ $dcontact['registrant'] = (string)$r->registrant;
+ foreach($r->contact as $e) {
+ $type = (string)$e->attributes()->type;
+ $dcontact[$type] = (string)$e;
+ }
+
+ $contact = array();
+ foreach($dcontact as $id) {
+ if (isset($contact[$id])) {
+ continue;
+ }
+
+ $from = $to = array();
+ $from[] = '/{{ id }}/';
+ $to[] = htmlspecialchars($id);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-contact-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ id }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:contact-1.0')->infData[0];
+ $contact[$id] = array();
+ $c = & $contact[$id];
+ foreach($r->postalInfo as $e) {
+ $c["Name"] = (string)$e->name;
+ $c["Organization"] = (string)$e->org;
+ for ($i = 0; $i <= 2; $i++) {
+ $c["Street " . ($i + 1) ] = (string)$e->addr->street[$i];
+ }
+
+ if (empty($c["Street 3"])) {
+ unset($c["street3"]);
+ }
+
+ $c["City"] = (string)$e->addr->city;
+ $c["State or Province"] = (string)$e->addr->sp;
+ $c["Postal Code"] = (string)$e->addr->pc;
+ $c["Country Code"] = (string)$e->addr->cc;
+ break;
+ }
+
+ $c["Phone"] = (string)$r->voice;
+ $c["Fax"] = (string)$r->fax;
+ $c["Email"] = (string)$r->email;
+ }
+
+ foreach($dcontact as $type => $id) {
+ if ($type == 'registrant') {
+ $type = 'Registrant';
+ }
+ elseif ($type == 'admin') {
+ $type = 'Administrator';
+ }
+ elseif ($type == 'tech') {
+ $type = 'Technical';
+ }
+ elseif ($type == 'billing') {
+ $type = 'Billing';
+ }
+ else {
+ continue;
+ }
+
+ $return[$type] = $contact[$id];
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_SaveContactDetails($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $dcontact = array();
+ $dcontact['registrant'] = (string)$r->registrant;
+ foreach($r->contact as $e) {
+ $type = (string)$e->attributes()->type;
+ $dcontact[$type] = (string)$e;
+ }
+
+ foreach($dcontact as $type => $id) {
+ $a = array();
+ if ($type == 'registrant') {
+ $a = $params['contactdetails']['Registrant'];
+ }
+ elseif ($type == 'admin') {
+ $a = $params['contactdetails']['Administrator'];
+ }
+ elseif ($type == 'tech') {
+ $a = $params['contactdetails']['Technical'];
+ }
+ elseif ($type == 'billing') {
+ $a = $params['contactdetails']['Billing'];
+ }
+
+ if (empty($a)) {
+ continue;
+ }
+
+ $from = $to = array();
+
+ $from[] = '/{{ id }}/';
+ $to[] = htmlspecialchars($id);
+
+ $from[] = '/{{ name }}/';
+ $name = ($a['Name'] ? $a['Name'] : $a['Full Name']);
+ $to[] = htmlspecialchars($name);
+
+ $from[] = '/{{ org }}/';
+ $org = ($a['Organization'] ? $a['Organization'] : $a['Organisation Name']);
+ $to[] = htmlspecialchars($org);
+
+ $from[] = '/{{ street1 }}/';
+ $street1 = ($a['Street 1'] ? $a['Street 1'] : $a['Address 1']);
+ $to[] = htmlspecialchars($street1);
+
+ $from[] = '/{{ street2 }}/';
+ $street2 = ($a['Street 2'] ? $a['Street 2'] : $a['Address 2']);
+ $to[] = htmlspecialchars($street2);
+
+ $from[] = '/{{ street3 }}/';
+ $street3 = ($a['Street 3'] ? $a['Street 3'] : $a['Address 3']);
+ $to[] = htmlspecialchars($street3);
+
+ $from[] = '/{{ city }}/';
+ $to[] = htmlspecialchars($a['City']);
+
+ $from[] = '/{{ sp }}/';
+ $sp = ($a['State or Province'] ? $a['State or Province'] : $a['State']);
+ $to[] = htmlspecialchars($sp);
+
+ $from[] = '/{{ pc }}/';
+ $pc = ($a['Postal Code'] ? $a['Postal Code'] : $a['Postcode']);
+ $to[] = htmlspecialchars($pc);
+
+ $from[] = '/{{ cc }}/';
+ $cc = ($a['Country Code'] ? $a['Country Code'] : $a['Country']);
+ $to[] = htmlspecialchars($cc);
+
+ $from[] = '/{{ voice }}/';
+ $to[] = htmlspecialchars($a['Phone']);
+
+ $from[] = '/{{ fax }}/';
+ $to[] = htmlspecialchars($a['Fax']);
+
+ $from[] = '/{{ email }}/';
+ $to[] = htmlspecialchars($a['Email']);
+
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-contact-chg-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ id }}
+
+
+ {{ name }}
+ {{ org }}
+
+ {{ street1 }}
+ {{ street2 }}
+ {{ street3 }}
+ {{ city }}
+ {{ sp }}
+ {{ pc }}
+ {{ cc }}
+
+
+ {{ voice }}
+ {{ fax }}
+ {{ email }}
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_IDProtectToggle($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $dcontact = array();
+ $dcontact['registrant'] = (string)$r->registrant;
+ foreach($r->contact as $e) {
+ $type = (string)$e->attributes()->type;
+ $dcontact[$type] = (string)$e;
+ }
+
+ $contact = array();
+ foreach($dcontact as $id) {
+ if (isset($contact[$id])) {
+ continue;
+ }
+
+ $from = $to = array();
+ $from[] = '/{{ id }}/';
+ $to[] = htmlspecialchars($id);
+
+ $from[] = '/{{ flag }}/';
+ $to[] = ($params['protectenable'] ? 1 : 0);
+
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1) , 3));
+ $to[] = htmlspecialchars($params['RegistrarPrefix'] . '-contact-update-' . $clTRID);
+
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ id }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['RegistrarPrefix']);
+ }
+
+ return $return;
+}
+
+function verisign_GetEPPCode($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $eppcode = (string)$r->authInfo->pw;
+
+ // If EPP Code is returned, return it for display to the end user
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+ return array('eppcode' => $eppcode);
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_RegisterNameserver($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['nameserver']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-host-check-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:host-1.0')->chkData;
+ if (0 == (int)$r->cd[0]->name->attributes()->avail) {
+ throw new exception($r->cd[0]->name . " " . $r->cd[0]->reason);
+ }
+
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['nameserver']);
+ $from[] = '/{{ ip }}/';
+ $to[] = htmlspecialchars($params['ipaddress']);
+ $from[] = '/{{ v }}/';
+ $to[] = (preg_match('/:/', $params['ipaddress']) ? 'v6' : 'v4');
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-host-create-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+ {{ ip }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_ModifyNameserver($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['nameserver']);
+ $from[] = '/{{ ip1 }}/';
+ $to[] = htmlspecialchars($params['currentipaddress']);
+ $from[] = '/{{ v1 }}/';
+ $to[] = (preg_match('/:/', $params['currentipaddress']) ? 'v6' : 'v4');
+ $from[] = '/{{ ip2 }}/';
+ $to[] = htmlspecialchars($params['newipaddress']);
+ $from[] = '/{{ v2 }}/';
+ $to[] = (preg_match('/:/', $params['newipaddress']) ? 'v6' : 'v4');
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-host-update-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+ {{ ip2 }}
+
+
+ {{ ip1 }}
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_DeleteNameserver($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['nameserver']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-host-delete-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_RequestDelete($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-delete-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_manageDNSSECDSRecords($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+
+ if (isset($_POST['command']) && ($_POST['command'] === 'secDNSadd')) {
+ $keyTag = $_POST['keyTag'];
+ $alg = $_POST['alg'];
+ $digestType = $_POST['digestType'];
+ $digest = $_POST['digest'];
+
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+
+ $from[] = '/{{ keyTag }}/';
+ $to[] = htmlspecialchars($keyTag);
+
+ $from[] = '/{{ alg }}/';
+ $to[] = htmlspecialchars($alg);
+
+ $from[] = '/{{ digestType }}/';
+ $to[] = htmlspecialchars($digestType);
+
+ $from[] = '/{{ digest }}/';
+ $to[] = htmlspecialchars($digest);
+
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+
+
+ {{ keyTag }}
+ {{ alg }}
+ {{ digestType }}
+ {{ digest }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+
+ if (isset($_POST['command']) && ($_POST['command'] === 'secDNSrem')) {
+ $keyTag = $_POST['keyTag'];
+ $alg = $_POST['alg'];
+ $digestType = $_POST['digestType'];
+ $digest = $_POST['digest'];
+
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+
+ $from[] = '/{{ keyTag }}/';
+ $to[] = htmlspecialchars($keyTag);
+
+ $from[] = '/{{ alg }}/';
+ $to[] = htmlspecialchars($alg);
+
+ $from[] = '/{{ digestType }}/';
+ $to[] = htmlspecialchars($digestType);
+
+ $from[] = '/{{ digest }}/';
+ $to[] = htmlspecialchars($digest);
+
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+
+
+ {{ keyTag }}
+ {{ alg }}
+ {{ digestType }}
+ {{ digest }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+
+ $secDNSdsData = array();
+ if ($r->response->extension && $r->response->extension->children('urn:ietf:params:xml:ns:secDNS-1.1')->infData) {
+ $DSRecords = 'YES';
+ $i = 0;
+ $r = $r->response->extension->children('urn:ietf:params:xml:ns:secDNS-1.1')->infData;
+ foreach($r->dsData as $dsData) {
+ $i++;
+ $secDNSdsData[$i]["domainid"] = (int)$params['domainid'];
+ $secDNSdsData[$i]["keyTag"] = (string)$dsData->keyTag;
+ $secDNSdsData[$i]["alg"] = (int)$dsData->alg;
+ $secDNSdsData[$i]["digestType"] = (int)$dsData->digestType;
+ $secDNSdsData[$i]["digest"] = (string)$dsData->digest;
+ }
+ }
+ else {
+ $DSRecords = "You don't have any DS records";
+ }
+
+ $return = array(
+ 'templatefile' => 'manageDNSSECDSRecords',
+ 'requirelogin' => true,
+ 'vars' => array(
+ 'DSRecords' => $DSRecords,
+ 'DSRecordslist' => $secDNSdsData
+ )
+ );
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'templatefile' => 'manageDNSSECDSRecords',
+ 'requirelogin' => true,
+ 'vars' => array(
+ 'error' => $e->getMessage()
+ )
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_ClientAreaCustomButtonArray()
+{
+ $buttonarray = array(
+ Lang::Trans('Manage DNSSEC DS Records') => 'manageDNSSECDSRecords'
+ );
+
+ return $buttonarray;
+}
+
+function verisign_AdminCustomButtonArray($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $domainid = getNamingoDomainId($params['domainid']);
+
+ // $domain = Capsule::table('tbldomains')->where('id', $domainid)->first();
+
+ $domain = Capsule::table('namingo_domain_status')->where('domain_id', '=', $domainid)->where('status', '=', 'clientHold')->first();
+
+ if (isset($domain->status)) {
+ return array(
+ 'Unhold Domain' => 'UnHoldDomain'
+ );
+ }
+ else {
+ return array(
+ 'Put Domain On Hold' => 'OnHoldDomain'
+ );
+ }
+}
+
+function verisign_OnHoldDomain($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $status = array();
+ $existing_status = 'ok';
+ foreach($r->status as $e) {
+ $st = (string)$e->attributes()->s;
+ if ($st == 'clientHold') {
+ $existing_status = 'clientHold';
+ break;
+ }
+
+ if ($st == 'serverHold') {
+ $existing_status = 'serverHold';
+ break;
+ }
+ }
+
+ if ($existing_status == 'ok') {
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+ clientHold
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_UnHoldDomain($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $status = array();
+ $existing_status = 'ok';
+ foreach($r->status as $e) {
+ $st = (string)$e->attributes()->s;
+ if ($st == 'clientHold') {
+ $existing_status = 'clientHold';
+ break;
+ }
+ }
+
+ if ($existing_status == 'clientHold') {
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['domainname']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+ clientHold
+
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_TransferSync($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['sld'] . '.' . $params['tld']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-transfer-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->trnData;
+ $trStatus = (string)$r->trStatus;
+ $expDate = (string)$r->exDate;
+
+ Capsule::table('namingo_domain')
+ ->where('name', $params['domain'])
+ ->update(['trstatus' => $trStatus]);
+
+ switch ($trStatus) {
+ case 'pending':
+ $return['completed'] = false;
+ break;
+ case 'clientApproved':
+ case 'serverApproved':
+ $return['completed'] = true;
+ $return['expirydate'] = date('Y-m-d', is_numeric($expDate) ? $expDate : strtotime($expDate));
+ break;
+ case 'clientRejected':
+ case 'clientCancelled':
+ case 'serverCancelled':
+ $return['failed'] = true;
+ $return['reason'] = $trStatus;
+ break;
+ default:
+ $return = array(
+ 'error' => sprintf('invalid transfer status: %s', $trStatus)
+ );
+ break;
+ }
+
+ return $return;
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+function verisign_Sync($params = array())
+{
+ _verisign_log(__FUNCTION__, $params);
+ $return = array();
+ try {
+ $s = _verisign_startEppClient($params);
+ $from = $to = array();
+ $from[] = '/{{ name }}/';
+ $to[] = htmlspecialchars($params['sld'] . '.' . $params['tld']);
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+
+ {{ name }}
+
+
+
+
+ dotCOM
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $s->write($xml, __FUNCTION__);
+ $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData;
+ $expDate = (string)$r->exDate;
+ $roid = (string)$r->roid;
+ $timestamp = strtotime($expDate);
+
+ if ($timestamp === false) {
+ return array(
+ 'error' => 'Empty expDate date for domain: ' . $params['domain']
+ );
+ }
+
+ $expDate = preg_replace("/^(\d+\-\d+\-\d+)\D.*$/", "$1", $expDate);
+
+ // Format `exDate` to `YYYY-MM-DD HH:MM:SS.000`
+ $formattedExpDate = date('Y-m-d H:i:s.000', $timestamp);
+
+ Capsule::table('namingo_domain')
+ ->where('name', $params['domain'])
+ ->update([
+ 'exdate' => $formattedExpDate,
+ 'registry_domain_id' => $roid
+ ]);
+
+ if ($timestamp < time()) {
+ return array(
+ 'expirydate' => $expDate,
+ 'expired' => true
+ );
+ }
+ else {
+ return array(
+ 'expirydate' => $expDate,
+ 'active' => true
+ );
+ }
+ }
+
+ catch(exception $e) {
+ $return = array(
+ 'error' => $e->getMessage()
+ );
+ }
+
+ if (!empty($s)) {
+ $s->logout($params['registrarprefix']);
+ }
+
+ return $return;
+}
+
+class verisign_epp_client
+
+{
+ var $socket;
+ var $isLogined = false;
+ var $params;
+ function __construct($params)
+ {
+ $this->params = $params;
+ $verify_peer = false;
+ if ($params['verify_peer'] == 'on') {
+ $verify_peer = true;
+ }
+ $ssl = array(
+ 'verify_peer' => $verify_peer,
+ 'cafile' => $params['cafile'],
+ 'local_cert' => $params['local_cert'],
+ 'local_pk' => $params['local_pk'],
+ 'passphrase' => $params['passphrase']
+ );
+ $host = $params['host'];
+ $port = $params['port'];
+
+ if ($host) {
+ $this->connect($host, $port, $ssl);
+ }
+ }
+
+ function connect($host, $port = 700, $ssl, $timeout = 30)
+ {
+ ini_set('display_errors', true);
+ error_reporting(E_ALL);
+
+ // echo '';print_r($host);
+ // print_r($this->params);
+ // exit;
+
+ if ($host != $this->params['host']) {
+ throw new exception("Unknown EPP server '$host'");
+ }
+
+ $tls_version = '1.2';
+ if ($this->params['tls_version'] == 'on') {
+ $tls_version = '1.3';
+ }
+
+ $opts = array(
+ 'ssl' => array(
+ 'verify_peer' => $ssl['verify_peer'],
+ 'verify_peer_name' => false,
+ 'verify_host' => false,
+ //'cafile' => __DIR__ . '/' . $ssl['cafile'],
+ 'local_cert' => __DIR__ . '/' . $ssl['local_cert'],
+ 'local_pk' => __DIR__ . '/' . $ssl['local_pk'],
+ //'passphrase' => $ssl['passphrase'],
+ 'allow_self_signed' => true
+ )
+ );
+ $context = stream_context_create($opts);
+ $this->socket = stream_socket_client("tlsv{$tls_version}://{$host}:{$port}", $errno, $errmsg, $timeout, STREAM_CLIENT_CONNECT, $context);
+
+
+ if (!$this->socket) {
+ throw new exception("Cannot connect to server '{$host}': {$errmsg}");
+ }
+
+ return $this->read();
+ }
+
+ function login($login, $pwd, $prefix)
+ {
+ $from = $to = array();
+ $from[] = '/{{ clID }}/';
+ $to[] = htmlspecialchars($login);
+ $from[] = '/{{ pw }}/';
+ $to[] = $pwd;
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($prefix . '-login-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+ {{ clID }}
+
+
+ 1.0
+ en
+
+
+ urn:ietf:params:xml:ns:domain-1.0
+ urn:ietf:params:xml:ns:contact-1.0
+ urn:ietf:params:xml:ns:host-1.0
+ http://www.verisign.com/epp/registry-1.0
+ http://www.verisign.com/epp/lowbalance-poll-1.0
+ http://www.verisign.com/epp/rgp-poll-1.0
+
+ urn:ietf:params:xml:ns:secDNS-1.1
+ urn:ietf:params:xml:ns:epp:loginSec-1.0
+ http://www.verisign.com/epp/whoisInf-1.0
+ http://www.verisign.com/epp/idnLang-1.0
+ urn:ietf:params:xml:ns:coa-1.0
+ http://www.verisign-grs.com/epp/namestoreExt-1.1
+ http://www.verisign.com/epp/sync-1.0
+ http://www.verisign.com/epp/relatedDomain-1.0
+ urn:ietf:params:xml:ns:verificationCode-1.0
+ urn:ietf:params:xml:ns:rgp-1.0
+ urn:ietf:params:xml:ns:changePoll-1.0
+
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $this->write($xml, __FUNCTION__);
+ $this->isLogined = true;
+ return true;
+ }
+
+ function logout($prefix)
+ {
+ if (!$this->isLogined) {
+ return true;
+ }
+
+ $from = $to = array();
+ $from[] = '/{{ clTRID }}/';
+ $clTRID = str_replace('.', '', round(microtime(1), 3));
+ $to[] = htmlspecialchars($prefix . '-logout-' . $clTRID);
+ $xml = preg_replace($from, $to, '
+
+
+
+ {{ clTRID }}
+
+ ');
+ $r = $this->write($xml, __FUNCTION__);
+ $this->isLogined = false;
+ return true;
+ }
+
+ function read()
+ {
+ _verisign_log('================= read-this =================', $this);
+ $hdr = stream_get_contents($this->socket, 4);
+ if ($hdr === false) {
+ throw new exception('Connection appears to have closed.');
+ }
+ if (strlen($hdr) < 4) {
+ throw new exception('Failed to read header from the connection.');
+ }
+ $unpacked = unpack('N', $hdr);
+ $xml = fread($this->socket, ($unpacked[1] - 4));
+ $xml = preg_replace('/>', ">\n<", $xml);
+ _verisign_log('================= read =================', $xml);
+ return $xml;
+ }
+
+ function write($xml, $action = 'Unknown')
+ {
+ _verisign_log('================= send-this =================', $this);
+ _verisign_log('================= send =================', $xml);
+ if (fwrite($this->socket, pack('N', (strlen($xml) + 4)) . $xml) === false) {
+ throw new exception('Error writing to the connection.');
+ }
+ $r = simplexml_load_string($this->read());
+ _verisign_modulelog($xml, $r, $action);
+ if (isset($r->response) && $r->response->result->attributes()->code >= 2000) {
+ throw new exception($r->response->result->msg);
+ }
+ return $r;
+ }
+
+ function disconnect()
+ {
+ $result = fclose($this->socket);
+ if (!$result) {
+ throw new exception('Error closing the connection.');
+ }
+ $this->socket = null;
+ return $result;
+ }
+
+ function generateObjectPW($objType = 'none')
+ {
+ $result = '';
+ $uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ $lowercaseChars = "abcdefghijklmnopqrstuvwxyz";
+ $numbers = "1234567890";
+ $specialSymbols = "!=+-";
+ $minLength = 16;
+ $maxLength = 16;
+ $length = mt_rand($minLength, $maxLength);
+
+ // Include at least one character from each set
+ $result .= $uppercaseChars[mt_rand(0, strlen($uppercaseChars) - 1)];
+ $result .= $lowercaseChars[mt_rand(0, strlen($lowercaseChars) - 1)];
+ $result .= $numbers[mt_rand(0, strlen($numbers) - 1)];
+ $result .= $specialSymbols[mt_rand(0, strlen($specialSymbols) - 1)];
+
+ // Append random characters to reach the desired length
+ while (strlen($result) < $length) {
+ $chars = $uppercaseChars . $lowercaseChars . $numbers . $specialSymbols;
+ $result .= $chars[mt_rand(0, strlen($chars) - 1)];
+ }
+
+ return $result;
+ }
+
+ function generateRandomString()
+ {
+ $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ $randomString = '';
+ for ($i = 0; $i < 16; $i++) {
+ $randomString .= $characters[rand(0, strlen($characters) - 1)];
+ }
+ return $randomString;
+ }
+
+}
+
+function _verisign_modulelog($send, $responsedata, $action)
+{
+ $from = $to = array();
+ $from[] = "/[^<]*<\/clID>/i";
+ $to[] = 'Not disclosed clID ';
+ $from[] = "/[^<]*<\/pw>/i";
+ $to[] = 'Not disclosed pw ';
+ $sendforlog = preg_replace($from, $to, $send);
+ logModuleCall('epp',$action,$sendforlog,$responsedata);
+}
+
+function _verisign_log($func, $params = false)
+{
+
+ // comment line below to see logs
+ //return true;
+
+ $handle = fopen(dirname(__FILE__) . '/verisign.log', 'a');
+ ob_start();
+ echo "\n================= $func =================\n";
+ print_r($params);
+ $text = ob_get_contents();
+ ob_end_clean();
+ fwrite($handle, $text);
+ fclose($handle);
+}
+
+function insertContacts($params, $contacts) {
+ $contactIds = [];
+
+ for ($i = 1; $i <= 4; $i++) {
+ // Insert into namingo_contact table
+ $contactId = Capsule::table('namingo_contact')->insertGetId([
+ 'identifier' => $contacts[$i],
+ 'voice' => $params['fullphonenumber'],
+ 'email' => $params['email'],
+ 'name' => $params['firstname'] . ' ' . $params['lastname'],
+ 'org' => $params['companyname'],
+ 'street1' => $params['address1'],
+ 'street2' => $params['address2'],
+ 'street3' => $params['address3'],
+ 'city' => $params['city'],
+ 'sp' => $params['state'],
+ 'pc' => $params['postcode'],
+ 'cc' => $params['country'],
+ 'clid' => 1,
+ 'crdate' => date('Y-m-d H:i:s.u')
+ ]);
+
+ // Save the last insert ID
+ $contactIds[] = $contactId;
+ }
+
+ return $contactIds;
+}
+
+function insertDomain($params, $contactIds) {
+ // Calculate expiry date
+ $crdate = date('Y-m-d H:i:s.u');
+ $exdate = date('Y-m-d H:i:s.u', strtotime("+{$params['regperiod']} years"));
+
+ // Insert into namingo_domain table
+ $domainId = Capsule::table('namingo_domain')->insertGetId([
+ 'name' => $params['domainname'],
+ 'registry_domain_id' => '',
+ 'clid' => 1,
+ 'crid' => 1,
+ 'crdate' => $crdate,
+ 'exdate' => $exdate,
+ 'registrant' => $contactIds[0] ?? null, // Registrant contact ID
+ 'admin' => $contactIds[1] ?? null, // Admin contact ID
+ 'tech' => $contactIds[2] ?? null, // Tech contact ID
+ 'billing' => $contactIds[3] ?? null, // Billing contact ID
+ 'ns1' => $params['ns1'] ?? null, // Name servers
+ 'ns2' => $params['ns2'] ?? null,
+ 'ns3' => $params['ns3'] ?? null,
+ 'ns4' => $params['ns4'] ?? null,
+ 'ns5' => $params['ns5'] ?? null
+ ]);
+
+ return $domainId;
+}
+
+function getNamingoDomainId($whmcsDomainId) {
+ // Retrieve the `namingo_domain` ID in a single query using a join
+ $namingoDomain = Capsule::table('namingo_domain')
+ ->join('tbldomains', 'namingo_domain.name', '=', 'tbldomains.domain')
+ ->where('tbldomains.id', $whmcsDomainId)
+ ->select('namingo_domain.id')
+ ->first();
+
+ // Return the `id` from `namingo_domain` if found, otherwise null
+ return $namingoDomain ? $namingoDomain->id : null;
+}
+
+?>
\ No newline at end of file
diff --git a/whmcs.json b/whmcs.json
new file mode 100644
index 0000000..386a052
--- /dev/null
+++ b/whmcs.json
@@ -0,0 +1,23 @@
+{
+ "schema": "1.0",
+ "type": "whmcs-registrars",
+ "name": "verisign",
+ "license": "MIT",
+ "category": "domains",
+ "description": {
+ "name": "Namingo EPP (VeriSign)",
+ "tagline": "This module supports all gTLDs that use the VeriSign platform"
+ },
+ "logo": {
+ "filename": "logo.gif"
+ },
+ "support": {
+ "homepage": "https:\/\/namingo.org\/"
+ },
+ "authors": [
+ {
+ "name": "Namingo",
+ "homepage": "https:\/\/namingo.org\/"
+ }
+ ]
+}