Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • awit-whmcs/whmcs-coza-epp
  • weheartwebsites/whmcs-coza-epp
  • qbitza/whmcs-coza-epp
  • wyrie/whmcs-coza-epp
  • Woklet/whmcs-coza-epp
  • jaymcc/whmcs-coza-epp
  • cmcawood/whmcs-coza-epp
7 results
Show changes
Commits on Source (40)
See http://devlabs.linuxassist.net/projects/whmcs-coza-epp
See http://gitlab.devlabs.linuxassist.net/awit-whmcs/whmcs-coza-epp/wikis/home
v.0.1.x to v1.0.0:
- Support added for .web.za, .org.za and .net.za
v0.1.0 to v0.1.1:
- Remove cronjob for modules/registrars/cozaepp/cozaeppsync.php, this is done by WHMCS automagically
#!/usr/bin/env php
<?php
# Copyright (c) 2012-2013, AllWorldIT
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Official Website:
# http://devlabs.linuxassist.net/projects/whmcs-coza-epp
# Lead developer:
# Nigel Kukard <nkukard@lbsd.net>
# ! ! P L E A S E N O T E ! !
# * If you make changes to this file, please consider contributing
# anything useful back to the community. Don't be a sour prick.
# * If you find this module useful please consider making a
# donation to support modules like this.
# WHMCS hosting, theming, module development, payment gateway
# integration, customizations and consulting all available from
# http://allworldit.com
# ! ! CONFIGURATION REQUIRED ! !
# Set the path below to the dbconnect.php file of your WHMCS installation.
$dbconnpath = dirname(__FILE__) . '/../init.php';
// Function that displays help
function _displayHelp() {
echo "usage: {$argv[0]} [--help|-h] <command> [<args>]\n\nAvailable commands are:\n\n changepassword Change ZACR account password.";
}
// This file brings in a few constants we need
require_once $dbconnpath;
// Setup include dir
$include_path = ROOTDIR . '/modules/registrars/cozaepp';
set_include_path($include_path . PATH_SEPARATOR . get_include_path());
// Include EPP stuff we need
require_once 'cozaepp.php';
// Additional functions we need
require_once ROOTDIR . '/includes/functions.php';
// Include registrar functions aswell
require_once ROOTDIR . '/includes/registrarfunctions.php';
// Changes old password to given new password for the specified SLD
function changePassword($sld, $current_password, $new_password)
{
// Grab module parameters
$params = getregistrarconfigoptions('cozaepp');
try {
$client = _cozaepp_Client($sld);
$result = $client->request('
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<login>
<clID>'.$params['Username'].'</clID>
<pw>'.$current_password.'</pw>
<newPW>'.$new_password.'</newPW>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
</svcs>
</login>
</command>
</epp>');
$doc= new DOMDocument();
$doc->loadXML($result);
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if ($coderes != '1000') {
$values["error"] = "ChangePassword($sld): Code ($coderes) $msg";
return $values;
}
$values['status'] = $msg;
} catch (Exception $e) {
$values["error"] = 'changePassword/EPP: '.$e->getMessage();
return $values;
}
return $values;
}
$_command = strtolower($argv[1]);
switch ($_command) {
case 'changepassword':
if (empty($argv['2']) || empty($argv['3']) || empty($argv['4'])) {
echo "\033[1;31mError: changepassword expects 3 arguments.\033[1;0m\n\n";
echo "{$argv[0]} changepassword <sld> <current password> <new password>\n\n";
exit(1);
}
$res = changePassword($argv['2'], $argv['3'], $argv['4']);
break;
case '-h':
exit(0);
case '--help':
exit(0);
default:
exit(1);
_displayHelp();
break;
}
if (is_array($res)) {
if (array_key_exists('error', $res)) {
echo $res['error'];
exit(2);
} elseif (array_key_exists('status', $res)) {
echo $res['status'];
exit(0);
}
} else {
echo "\033[1;31mError: Unexpected result from command call\033[1;0m\n\n";
var_dump($res);
}
<?
<?php
/**
* Copyright (c) 2012-2014, AllWorldIT
* Copyright (c) 2012-2015, AllWorldIT
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -46,7 +46,7 @@
*/
// This file brings in a few constants we need
require_once dirname(__FILE__) . '/../../../dbconnect.php';
require_once dirname(__FILE__) . '/../../../init.php';
// Setup include dir
$include_path = ROOTDIR . '/modules/registrars/cozaepp';
set_include_path($include_path . PATH_SEPARATOR . get_include_path());
......@@ -111,7 +111,7 @@ foreach ($domains as $domain) {
if ($doc->getElementsByTagName('autorenew') &&
$doc->getElementsByTagName('autorenew')->item(0) &&
strtolower(trim($doc->getElementsByTagName('autorenew')->item(0)->nodeValue)) != "false"
) {
) {
sleep(1);
// Disable autorenew via update
......
......@@ -35,7 +35,7 @@ function awit_cozaepp_config()
$configarray = array(
"name" => "AWIT COZAEPP",
"description" => "This module is to facilitate displaying of epp messages.",
"version" => "0.1",
"version" => "1.2",
"author" => "AllWorldIT",
"language" => "english",
"fields" => array(
......
......@@ -4,4 +4,3 @@ $_ADDONLANG['intro'] = "AWIT COZAEPP Module";
$_ADDONLANG['description'] = "This module is to facilitate displaying of epp messages.";
$_ADDONLANG['documentation'] = "Pending..";
?>
......@@ -55,7 +55,7 @@
* @return a string containing the server <greeting>
*/
function connect($host, $port=700, $timeout=1, $ssl=true, $context=NULL) {
$target = sprintf('%s://%s:%d', ($ssl === true ? 'tls' : 'tcp'), $host, $port);
$target = sprintf('%s://%s:%d', ($ssl === true ? 'ssl' : 'tcp'), $host, $port);
if (is_resource($context)) {
$result = stream_socket_client($target, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);
......
......@@ -54,7 +54,7 @@ class Net_EPP_Protocol {
// Update metadata
$info = stream_get_meta_data($socket);
$time_end = microtime(true);
if (($time_end - $time_start) > 10000000) {
if (($time_end - $time_start) > 10) {
throw new exception('Timeout while reading from EPP Server');
}
}
......@@ -93,7 +93,7 @@ class Net_EPP_Protocol {
// Update metadata
$info = stream_get_meta_data($socket);
$time_end = microtime(true);
if (($time_end - $time_start) > 10000000) {
if (($time_end - $time_start) > 10) {
throw new exception('Timeout while writing to EPP Server');
}
}
......
<?php
# Copyright (c) 2012-2013, AllWorldIT
# Copyright (c) 2012-2018, AllWorldIT
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -35,7 +35,7 @@
# integration, customizations and consulting all available from
# http://allworldit.com
// Make sure we not being accssed directly
# Make sure we not being accssed directly
if (!defined("WHMCS"))
die("This file cannot be accessed directly");
......@@ -44,8 +44,6 @@ function cozaepp_getConfigArray() {
$configarray = array(
"Username" => array( "Type" => "text", "Size" => "20", "Description" => "Enter your username here" ),
"Password" => array( "Type" => "password", "Size" => "20", "Description" => "Enter your password here" ),
"Server" => array( "Type" => "text", "Size" => "20", "Description" => "Enter EPP Server Address" ),
"Port" => array( "Type" => "text", "Size" => "20", "Description" => "Enter EPP Server Port" ),
"SSL" => array( "Type" => "yesno" ),
"Certificate" => array( "Type" => "text", "Description" => "Path of certificate .pem" )
);
......@@ -67,12 +65,12 @@ function cozaepp_GetNameservers($params) {
# Grab variables
$sld = $params["sld"];
$tld = $params["tld"];
$domain = "$sld.$tld";
$domain = strtolower("$sld.$tld");
# Get client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Get list of nameservers for domain
$result = $client->request($xml = '
......@@ -129,7 +127,7 @@ function cozaepp_SaveNameservers($params) {
# Grab variables
$sld = $params["sld"];
$tld = $params["tld"];
$domain = strtolower("$sld.$tld");
# Generate XML for nameservers
if ($nameserver1 = $params["ns1"]) {
......@@ -168,7 +166,7 @@ function cozaepp_SaveNameservers($params) {
# Get client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab list of current nameservers
$request = $client->request( $xml = '
......@@ -177,7 +175,7 @@ function cozaepp_SaveNameservers($params) {
<epp:command>
<epp:info>
<domain:info xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:name hosts="all">'.$sld.'.'.$tld.'</domain:name>
<domain:name hosts="all">'.$domain.'</domain:name>
</domain:info>
</epp:info>
</epp:command>
......@@ -193,7 +191,7 @@ function cozaepp_SaveNameservers($params) {
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check if result is ok
if($coderes != '1000') {
$values["error"] = "SaveNameservers/domain-info($sld.$tld): Code ($coderes) $msg";
$values["error"] = "SaveNameservers/domain-info($domain): Code ($coderes) $msg";
return $values;
}
......@@ -217,7 +215,7 @@ function cozaepp_SaveNameservers($params) {
<epp:command>
<epp:update>
<domain:update>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
<domain:add>
<domain:ns>'.$add_hosts.' </domain:ns>
</domain:add>
......@@ -244,7 +242,7 @@ function cozaepp_SaveNameservers($params) {
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check if result is ok
if($coderes != '1001') {
$values["error"] = "SaveNameservers/domain-update($sld.$tld): Code ($coderes) $msg";
$values["error"] = "SaveNameservers/domain-update($domain): Code ($coderes) $msg";
return $values;
}
......@@ -265,7 +263,7 @@ function cozaepp_GetRegistrarLock($params) {
# Grab variables
$sld = $params["sld"];
$tld = $params["tld"];
$domain = strtolower("$sld.$tld");
# Get lock status
$lock = 0;
......@@ -277,20 +275,24 @@ function cozaepp_GetRegistrarLock($params) {
return $lockstatus;
}
# NOT IMPLEMENTED
function cozaepp_SaveRegistrarLock($params) {
$values["error"] = "SaveRegistrarLock: Current co.za policy does not allow for the addition of client-side statuses on domains.";
return $values;
}
# Function to retrieve an available contact id
function _cozaepp_CheckContact($prehash) {
$prehash = $prehash . time() . rand(0, 1000000);
function _cozaepp_CheckContact($domain,$type) {
$prehash = $domain . time() . rand(0, 1000000) . $type;
$contactid = substr(md5($prehash), 0,15);
# Get client instance and check for available contact id
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
$contactAvailable = 0;
$count = 0;
......@@ -353,11 +355,14 @@ function _cozaepp_CheckContact($prehash) {
}
# Function to register domain
function cozaepp_RegisterDomain($params) {
# Grab varaibles
$sld = $params["sld"];
$tld = $params["tld"];
$domain = strtolower("$sld.$tld");
$regperiod = $params["regperiod"];
# Get registrant details
......@@ -381,9 +386,13 @@ function cozaepp_RegisterDomain($params) {
$AdminPostalCode = $params["adminpostcode"];
$AdminCountry = $params["admincountry"];
$AdminEmailAddress = $params["adminemail"];
$AdminPhone = $params["adminphonenumber"];
# Our details
$contactid = substr(md5($sld . '.' . $tld), 0,15);
$AdminPhone = $params["adminfullphonenumber"];
# Registrar contactid hash
$contactid = substr(md5($domain), 0,15);
# Admin/Tech/Billing contactid hash
$additional_contactid = substr(md5($AdminFirstName.$AdminLastName), 0,15);
# Generate XML for namseverss
if ($nameserver1 = $params["ns1"]) {
......@@ -424,7 +433,10 @@ function cozaepp_RegisterDomain($params) {
# Get client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# registry.net.za expects 'coza' as the password
$pw = "coza";
# Send registration
$request = $client->request($xml = '
......@@ -449,7 +461,7 @@ function cozaepp_RegisterDomain($params) {
<contact:fax></contact:fax>
<contact:email>'.$RegistrantEmailAddress.'</contact:email>
<contact:authInfo>
<contact:pw>AxA8AjXbAH'.rand().rand().'</contact:pw>
<contact:pw>'.$pw.'</contact:pw>
</contact:authInfo>
</contact:create>
</epp:create>
......@@ -476,18 +488,84 @@ function cozaepp_RegisterDomain($params) {
$values["status"] = $msg;
$request = $client->request($xml = '
$domaincreate = '
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:cozadomain="http://co.za/epp/extensions/cozadomain-1-0"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<epp:command>
<epp:create>
<domain:create xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
<domain:ns>'.$add_hosts.'</domain:ns>
<domain:registrant>'.$contactid.'</domain:registrant>
<domain:registrant>'.$contactid.'</domain:registrant>';
# Some SLDs require the presence of admin, billing and tech contacts.
# Check if our domain has the requirement and get/create the required contact id.
$_server = _cozaepp_SldLookup($domain);
if ($_server['additional_contacts']) {
# Generate a random password to be used for the additional contact
$pw = substr(md5($domain . time() . rand(0, 1000000)), 0,15);
$request = $client->request($xml = '
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<epp:command>
<epp:create>
<contact:create xsi:schemaLocation="urn:ietf:params:xml:ns:contact-1.0 contact-1.0.xsd">
<contact:id>'.$additional_contactid.'</contact:id>
<contact:postalInfo type="loc">
<contact:name>'.$AdminFirstName.' '.$AdminLastName.'</contact:name>
<contact:addr>
<contact:street>'.$AdminAddress1.'</contact:street>
<contact:street>'.$AdminAddress2.'</contact:street>
<contact:city>'.$AdminCity.'</contact:city>
<contact:sp>'.$AdminStateProvince.'</contact:sp>
<contact:pc>'.$AdminPostalCode.'</contact:pc>
<contact:cc>'.$AdminCountry.'</contact:cc>
</contact:addr>
</contact:postalInfo>
<contact:voice>'.$AdminPhone.'</contact:voice>
<contact:fax></contact:fax>
<contact:email>'.$AdminEmailAddress.'</contact:email>
<contact:authInfo>
<contact:pw>'.$pw.'</contact:pw>
</contact:authInfo>
</contact:create>
</epp:create>
</epp:command>
</epp:epp>
');
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', 'RegisterDomain', $xml, $request);
# Pull off status
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes == '1000') {
$values['contact'] = 'Contact Created';
} else if($coderes == '2302') {
$values['contact'] = 'Contact Already exists';
} else {
$values["error"] = "RegisterDomain/additional-create($additional_contactid): Code ($coderes) $msg";
return $values;
}
$domaincreate .= '
<domain:contact type="admin">'.$additional_contactid.'</domain:contact>
<domain:contact type="tech">'.$additional_contactid.'</domain:contact>
<domain:contact type="billing">'.$additional_contactid.'</domain:contact>';
}
# registry.net.za expects 'coza' as the password
$pw = "coza";
$domaincreate .= '
<domain:authInfo>
<domain:pw>coza</domain:pw>
<domain:pw>'.$pw.'</domain:pw>
</domain:authInfo>
</domain:create>
</epp:create>
......@@ -498,15 +576,17 @@ function cozaepp_RegisterDomain($params) {
</epp:extension>
</epp:command>
</epp:epp>
');
';
$request = $client->request($domaincreate);
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', 'RegisterDomain', $xml, $request);
logModuleCall('Cozaepp', 'RegisterDomain', $domaincreate, $request);
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1000') {
$values["error"] = "RegisterDomain/domain-create($sld.$tld): Code ($coderes) $msg";
$values["error"] = "RegisterDomain/domain-create($domain): Code ($coderes) $msg";
return $values;
}
......@@ -527,6 +607,7 @@ function cozaepp_TransferDomain($params) {
$testmode = $params["TestMode"];
$sld = $params["sld"];
$tld = $params["tld"];
$domain = strtolower("$sld.$tld");
# Domain info
$regperiod = $params["regperiod"];
......@@ -554,13 +635,13 @@ function cozaepp_TransferDomain($params) {
$AdminPostalCode = $params["adminpostcode"];
$AdminCountry = $params["admincountry"];
$AdminEmailAddress = $params["adminemail"];
$AdminPhone = $params["adminphonenumber"];
$AdminPhone = $params["adminfullphonenumber"];
# Our details
$contactid = substr(md5($sld . '.' . $tld), 0,15);
$contactid = substr(md5($domain), 0,15);
# Get client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Initiate transfer
$request = $client->request($xml = '
......@@ -568,7 +649,7 @@ function cozaepp_TransferDomain($params) {
<epp:command>
<epp:transfer op="request">
<domain:transfer>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
</domain:transfer>
</epp:transfer>
</epp:command>
......@@ -584,55 +665,7 @@ function cozaepp_TransferDomain($params) {
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# We should get a 1001 back
if($coderes != '1001') {
$values["error"] = "TransferDomain/domain-transfer($sld.$tld): Code ($coderes) $msg";
return $values;
}
$values["status"] = $msg;
# Create contact details
$request = $client->request($xml = '
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:contact="urn:ietf:params:xml:ns:contact-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<epp:command>
<epp:create>
<contact:create xsi:schemaLocation="urn:ietf:params:xml:ns:contact-1.0 contact-1.0.xsd">
<contact:id>'.$contactid.'</contact:id>
<contact:postalInfo type="loc">
<contact:name>'.$RegistrantFirstName.' '.$RegistrantLastName.'</contact:name>
<contact:addr>
<contact:street>'.$RegistrantAddress1.'</contact:street>
<contact:street>'.$RegistrantAddress2.'</contact:street>
<contact:city>'.$RegistrantCity.'</contact:city>
<contact:sp>'.$RegistrantStateProvince.'</contact:sp>
<contact:pc>'.$RegistrantPostalCode.'</contact:pc>
<contact:cc>'.$RegistrantCountry.'</contact:cc>
</contact:addr>
</contact:postalInfo>
<contact:voice>'.$RegistrantPhone.'</contact:voice>
<contact:fax></contact:fax>
<contact:email>'.$RegistrantEmailAddress.'</contact:email>
<contact:authInfo>
<contact:pw>AxA8AjXbAH'.rand().rand().'</contact:pw>
</contact:authInfo>
</contact:create>
</epp:create>
</epp:command>
</epp:epp>
');
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', 'TransferDomain', $xml, $request);
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes == '1000') {
$values['contact'] = 'Contact Created';
} else if($coderes == '2302') {
$values['contact'] = 'Contact Already exists';
} else {
$values["error"] = "TransferDomain/contact-create($contactid): Code ($coderes) $msg";
$values["error"] = "TransferDomain/domain-transfer($domain): Code ($coderes) $msg";
return $values;
}
......@@ -654,11 +687,12 @@ function cozaepp_RenewDomain($params) {
$sld = $params["sld"];
$tld = $params["tld"];
$regperiod = $params["regperiod"];
$domain = strtolower("$sld.$tld");
# Get client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Send renewal request
$request = $client->request($xml = '
......@@ -667,7 +701,7 @@ function cozaepp_RenewDomain($params) {
<epp:command>
<epp:info>
<domain:info xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:name hosts="all">'.$sld.'.'.$tld.'</domain:name>
<domain:name hosts="all">'.$domain.'</domain:name>
</domain:info>
</epp:info>
</epp:command>
......@@ -682,7 +716,7 @@ function cozaepp_RenewDomain($params) {
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1000') {
$values["error"] = "RenewDomain/domain-info($sld.$tld)): Code ($coderes) $msg";
$values["error"] = "RenewDomain/domain-info($domain)): Code ($coderes) $msg";
return $values;
}
......@@ -691,7 +725,7 @@ function cozaepp_RenewDomain($params) {
# Sanitize expiry date
$expdate = substr($doc->getElementsByTagName('exDate')->item(0)->nodeValue,0,10);
if (empty($expdate)) {
$values["error"] = "RenewDomain/domain-info($sld.$tld): Domain info not available";
$values["error"] = "RenewDomain/domain-info($domain): Domain info not available";
return $values;
}
......@@ -701,7 +735,7 @@ function cozaepp_RenewDomain($params) {
<epp:command>
<epp:renew>
<domain:renew>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
<domain:curExpDate>'.$expdate.'</domain:curExpDate>
</domain:renew>
</epp:renew>
......@@ -717,7 +751,7 @@ function cozaepp_RenewDomain($params) {
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1000') {
$values["error"] = "RenewDomain/domain-renew($sld.$tld,$expdate): Code (".$coderes.") ".$msg;
$values["error"] = "RenewDomain/domain-renew($domain,$expdate): Code (".$coderes.") ".$msg;
return $values;
}
......@@ -732,60 +766,88 @@ function cozaepp_RenewDomain($params) {
return $values;
}
function _getContactDetails($domain, $client = null) {
function __getContact($contactID,$client = null) {
# Get client instance
try {
if (!isset($client)) {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
}
# Grab domain info
# Grab contact info
$request = $client->request($xml = '
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<epp:command>
<epp:info>
<domain:info xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:name hosts="all">'.$domain.'</domain:name>
</domain:info>
<contact:info>
<contact:id>'.$contactID.'</contact:id>
</contact:info>
</epp:info>
</epp:command>
</epp:epp>
');
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', '_GetContactDetails', $xml, $request);
logModuleCall('Cozaepp', '__getContact', $xml, $request);
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check result
if($coderes != '1000') {
$values["error"] = "_GetContactDetails/domain-info($domain): Code (".$coderes.") ".$msg;
$values["error"] = "__getContact/contact-info($contactID): Code (".$coderes.") ".$msg;
return $values;
}
# Grab contact info
$registrant = $doc->getElementsByTagName('registrant')->item(0)->nodeValue;
if (empty($registrant)) {
$values["error"] = "_GetContactDetails/domain-info($domain): Registrant info not available";
return $values;
$nodes = $doc->getElementsByTagName('postalInfo');
for ($i = 0; ($i < $nodes->length); $i++) {
if ($nodes->item($i)->getAttributeNode('type')->nodeValue == 'loc') {
$childNodes = $nodes->item($i);
$results["Contact Name"] = $childNodes->getElementsByTagName('name')->item(0)->nodeValue;
$results["Organisation"] = $childNodes->getElementsByTagName('org')->item(0)->nodeValue;
$results["Address line 1"] = $childNodes->getElementsByTagName('street')->item(0)->nodeValue;
$results["Address line 2"] = $childNodes->getElementsByTagName('street')->item(1)->nodeValue;
$results["TownCity"] = $childNodes->getElementsByTagName('city')->item(0)->nodeValue;
$results["State"] = $childNodes->getElementsByTagName('sp')->item(0)->nodeValue;
$results["Zip code"] = $childNodes->getElementsByTagName('pc')->item(0)->nodeValue;
$results["Country Code"] = $childNodes->getElementsByTagName('cc')->item(0)->nodeValue;
}
}
# Grab contact info
$results["Phone"] = $doc->getElementsByTagName('voice')->item(0)->nodeValue;
$results["Email"] = $doc->getElementsByTagName('email')->item(0)->nodeValue;
return $results;
} catch (Exception $e) {
$values["error"] = '__getContact/EPP: '.$e->getMessage();
return $values;
}
}
function _getContactDetails($domain, $client = null) {
# Get client instance
try {
if (!isset($client)) {
$client = _cozaepp_Client($domain);
}
# Grab domain info
$request = $client->request($xml = '
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<epp:command>
<epp:info>
<contact:info>
<contact:id>'.$registrant.'</contact:id>
</contact:info>
<domain:info xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:name hosts="all">'.$domain.'</domain:name>
</domain:info>
</epp:info>
</epp:command>
</epp:epp>
');
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
......@@ -793,65 +855,114 @@ function _getContactDetails($domain, $client = null) {
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check result
if($coderes != '1000') {
$values["error"] = "_GetContactDetails/contact-info($registrant): Code (".$coderes.") ".$msg;
$values["error"] = "_GetContactDetails/domain-info($domain): Code (".$coderes.") ".$msg;
return $values;
}
$nodes = $doc->getElementsByTagName('postalInfo');
for ($i = 0; ($i < $nodes->length); $i++) {
if ($nodes->item($i)->getAttributeNode('type')->nodeValue == 'loc') {
$childNodes = $nodes->item($i);
$results["Registrant"]["Contact Name"] = $childNodes->getElementsByTagName('name')->item(0)->nodeValue;
$results["Registrant"]["Organisation"] = $childNodes->getElementsByTagName('org')->item(0)->nodeValue;
$results["Registrant"]["Address line 1"] = $childNodes->getElementsByTagName('street')->item(0)->nodeValue;
$results["Registrant"]["Address line 2"] = $childNodes->getElementsByTagName('street')->item(1)->nodeValue;
$results["Registrant"]["TownCity"] = $childNodes->getElementsByTagName('city')->item(0)->nodeValue;
$results["Registrant"]["State"] = $childNodes->getElementsByTagName('sp')->item(0)->nodeValue;
$results["Registrant"]["Zip code"] = $childNodes->getElementsByTagName('pc')->item(0)->nodeValue;
$results["Registrant"]["Country Code"] = $childNodes->getElementsByTagName('cc')->item(0)->nodeValue;
# Grab contact ID's
$registrantContactID = $doc->getElementsByTagName('registrant')->item(0)->nodeValue;
if (empty($registrantContactID)) {
$values["error"] = "_GetContactDetails/domain-info($domain): Registrant contact info not available => $request";
return $values;
}
$contactNodes = $doc->getElementsByTagName('contact');
foreach ($contactNodes as $contactNode) {
# Check if we have found the relevant contact nodes
$type = $contactNode->getAttribute('type');
if ($type == "admin") {
$adminContactID = $contactNode->nodeValue;
} elseif ($type == "tech") {
$techContactID = $contactNode->nodeValue;
} elseif ($type == "billing") {
$billingContactID = $contactNode->nodeValue;
}
}
$results["Registrant"]["Phone"] = $doc->getElementsByTagName('voice')->item(0)->nodeValue;
$results["Registrant"]["Email"] = $doc->getElementsByTagName('email')->item(0)->nodeValue;
if (empty($adminContactID)) {
$values["error"] = "_GetContactDetails/domain-info($domain): Admin contact info not available";
return $values;
}
if (empty($techContactID)) {
$values["error"] = "_GetContactDetails/domain-info($domain): Technical contact info not available";
return $values;
}
if (empty($billingContactID)) {
$values["error"] = "_GetContactDetails/domain-info($domain): Billing contact info not available";
return $values;
}
return $results;
} catch (Exception $e) {
$values["error"] = 'GetContactDetails/EPP: '.$e->getMessage();
$values["error"] = '_GetContactDetails/EPP: '.$e->getMessage();
return $values;
}
# Grab contacts
$registrantContactInfo = __getContact($registrantContactID,$client);
# If there was an error return it
if (isset($registrantContactInfo["error"])) {
return $registrantContactInfo;
}
$adminContactInfo = __getContact($adminContactID,$client);
# If there was an error return it
if (isset($adminContactInfo["error"])) {
return $adminContactInfo;
}
$techContactInfo = __getContact($techContactID,$client);
# If there was an error return it
if (isset($techContactInfo["error"])) {
return $techContactInfo;
}
$billingContactInfo = __getContact($billingContactID,$client);
# If there was an error return it
if (isset($billingContactInfo["error"])) {
return $billingContactInfo;
}
$results['Registrant'] = $registrantContactInfo;
$results['Admin'] = $adminContactInfo;
$results['Technical'] = $techContactInfo;
$results['Billing'] = $billingContactInfo;
return $results;
}
# Function to grab contact details
function cozaepp_GetContactDetails($params) {
# Grab variables
$sld = $params["sld"];
$tld = $params["tld"];
$domain = strtolower("$sld.$tld");
# Fetching contact details
$results = _getContactDetails($sld . '.' . $tld);
$contacts = _getContactDetails($domain);
# If there was an error return it
if (isset($results["error"])) {
return $results;
if (isset($contacts["error"])) {
return $contacts;
}
# What we going to do here is make sure all the attirbutes we return back are set
# If we don't do this WHMCS won't display the options for editing
foreach (
array("Contact Name","Organisation","Address line 1","Address line 2","TownCity","State","Zip code","Country Code","Phone","Email")
foreach (array("Registrant","Admin","Technical","Billing") as $type) {
foreach (
array("Contact Name","Organisation","Address line 1","Address line 2","TownCity","State","Zip code","Country Code",
"Phone","Email")
as $item
) {
# Check if the item is set
if ($results["Registrant"][$item] == "") {
# Just set it to -
$values["Registrant"][$item] = "-";
} else {
# We setting this here so we maintain the right order, else we get the set
# things first and all the unsets second, which looks crap
$values["Registrant"][$item] = $results["Registrant"][$item];
) {
# Check if the item is set
if (empty($contacts[$type][$item])) {
# Just set it to -
$values[$type][$item] = "-";
} else {
# We setting this here so we maintain the right order, else we get the set
# things first and all the unsets second, which looks crap
$values[$type][$item] = $contacts[$type][$item];
}
}
}
......@@ -860,27 +971,162 @@ function cozaepp_GetContactDetails($params) {
/**
* Catching all the different variations of params as encountered by clients
* This has only been reported to have occured in WHMCS 5.2 and 5.3.7
* References to the occurences of this particular issue can be found at the followinf urls:
* https://gitlab.devlabs.linuxassist.net/awit-whmcs/whmcs-coza-epp/issues/11#note_630
* http://lists.linuxassist.net/pipermail/whmcs-coza-epp_lists.linuxassist.net/2013-April/000319.html
*/
function _getContactDetailsFromParams($params,$type) {
$results = array();
$results["Contact Name"] = $params["contactdetails"][$type]["Contact Name"];
# Catching different variations of Organisation
if (isset($params["contactdetails"][$type]["Organisation"])) {
$results["Organisation"] = $params["contactdetails"][$type]["Organisation"];
} else if (isset($params["contactdetails"][$type]["Company Name"])) {
$results["Organisation"] = $params["contactdetails"][$type]["Company Name"];
} else {
$results["Organisation"] = "";
}
# Catching different variations of Address line 1
if (isset($params["contactdetails"][$type]["Address line 1"])) {
$results["Address line 1"] = $params["contactdetails"][$type]["Address line 1"];
} else if (isset($params["contactdetails"][$type]["Address 1"])) {
$results["Address line 1"] = $params["contactdetails"][$type]["Address 1"];
} else {
$results["Address line 1"] = "";
}
# Catching different variations of Address line 2
if (isset($params["contactdetails"][$type]["Address line 2"])) {
$results["Address line 2"] = $params["contactdetails"][$type]["Address line 2"];
} else if (isset($params["contactdetails"][$type]["Address 2"])) {
$results["Address line 2"] = $params["contactdetails"][$type]["Address 2"];
} else {
$results["Address line 2"] = "";
}
# Catching different variations of TownCity
if (isset($params["contactdetails"][$type]["TownCity"])) {
$results["TownCity"] = $params["contactdetails"][$type]["TownCity"];
} else if (isset($params["contactdetails"][$type]["City"])) {
$results["TownCity"] = $params["contactdetails"][$type]["City"];
} else {
$results["TownCity"] = "";
}
$results["State"] = $params["contactdetails"][$type]["State"];
# Catching different variations of Postal Code
if (isset($params["contactdetails"][$type]["Zip code"])) {
$results["Zip code"] = $params["contactdetails"][$type]["Zip code"];
} else if (isset($params["contactdetails"][$type]["ZIP Code"])) {
$results["Zip code"] = $params["contactdetails"][$type]["ZIP Code"];
} else if (isset($params["contactdetails"][$type]["Postcode"])) {
$results["Zip code"] = $params["contactdetails"][$type]["Postcode"];
} else {
$results["Zip code"] = "";
}
# Catching different variations of Country Code
if (isset($params["contactdetails"][$type]["Country Code"])) {
$results["Country Code"] = $params["contactdetails"][$type]["Country Code"];
} else if (isset($params["contactdetails"][$type]["Country"])) {
$results["Country Code"] = $params["contactdetails"][$type]["Country"];
} else {
$results["Country Code"] = "";
}
$results["Phone"] = $params["contactdetails"][$type]["Phone"];
$results["Email"] = $params["contactdetails"][$type]["Email"];
return $results;
}
# Function to actually do the saving of contact details
function __saveContact($contactID,$contacts,$type,$client = null) {
# Get client instance
try {
if (!isset($client)) {
$client = _cozaepp_Client($domain);
}
# Grab contact
$contact = $contacts[$type];
# Save contact details
$request = $client->request($xml = '
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
<epp:command>
<epp:update>
<contact:update>
<contact:id>'.$contactID.'</contact:id>
<contact:chg>
<contact:postalInfo type="loc">
<contact:name>'.$contact['Contact Name'].'</contact:name>
<contact:org>'.$contact['Organization'].'</contact:org>
<contact:addr>
<contact:street>'.$contact['Address line 1'].'</contact:street>
<contact:street>'.$contact['Address line 2'].'</contact:street>
<contact:city>'.$contact['TownCity'].'</contact:city>
<contact:sp>'.$contact['State'].'</contact:sp>
<contact:pc>'.$contact['Zip code'].'</contact:pc>
<contact:cc>'.$contact['Country Code'].'</contact:cc>
</contact:addr>
</contact:postalInfo>
<contact:voice>'.$contact['Phone'].'</contact:voice>
<contact:fax></contact:fax>
<contact:email>'.$contact['Email'].'</contact:email>
</contact:chg>
</contact:update>
</epp:update>
</epp:command>
</epp:epp>
');
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', 'SaveContactDetails', $xml, $request);
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1001') {
$values["error"] = "SaveContactDetails/contact-update($registrant): Code ($coderes) $msg";
return $values;
}
$values["status"] = $msg;
return $values;
} catch (Exception $e) {
$values["error"] = 'SaveContactDetails/EPP: '.$e->getMessage();
return $values;
}
}
# Function to save contact details
function cozaepp_SaveContactDetails($params) {
# Grab variables
$tld = $params["tld"];
$sld = $params["sld"];
$domain = strtolower("$sld.$tld");
# Registrant details
$registrant_name = $params["contactdetails"]["Registrant"]["Contact Name"];
$registrant_org = $params["contactdetails"]["Registrant"]["Organisation"];
$registrant_address1 = $params["contactdetails"]["Registrant"]["Address line 1"];
$registrant_address2 = $params["contactdetails"]["Registrant"]["Address line 2"];
$registrant_town = $params["contactdetails"]["Registrant"]["TownCity"];
$registrant_state = $params["contactdetails"]["Registrant"]["State"];
$registrant_zipcode = $params["contactdetails"]["Registrant"]["Zip code"];
$registrant_countrycode = $params["contactdetails"]["Registrant"]["Country Code"];
$registrant_phone = $params["contactdetails"]["Registrant"]["Phone"];
#$registrant_fax = '',
$registrant_email = $params["contactdetails"]["Registrant"]["Email"];
$registrantContactDetails = _getContactDetailsFromParams($params,"Registrant");
$adminContactDetails = _getContactDetailsFromParams($params,"Admin");
$technicalContactDetails = _getContactDetailsFromParams($params,"Technical");
$billingContactDetails = _getContactDetailsFromParams($params,"Billing");
# Get client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab domain info
$request = $client->request($xml = '
......@@ -889,7 +1135,7 @@ function cozaepp_SaveContactDetails($params) {
<epp:command>
<epp:info>
<domain:info xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:name hosts="all">'.$sld.'.'.$tld.'</domain:name>
<domain:name hosts="all">'.$domain.'</domain:name>
</domain:info>
</epp:info>
</epp:command>
......@@ -903,58 +1149,171 @@ function cozaepp_SaveContactDetails($params) {
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1000') {
$values["error"] = "SaveContactDetails/domain-info($sld.$tld): Code (".$coderes.") ".$msg;
$values["error"] = "SaveContactDetails/domain-info($domain): Code (".$coderes.") ".$msg;
return $values;
}
$values["status"] = $msg;
# Grab contact ID's
$registrantContactID = $doc->getElementsByTagName('registrant')->item(0)->nodeValue;
if (empty($registrantContactID)) {
$values["error"] = "_SaveContactDetails/domain-info($domain): Registrant contact info not available";
return $values;
}
# Time to do the update
$registrant = $doc->getElementsByTagName('registrant')->item(0)->nodeValue;
$contactNodes = $doc->getElementsByTagName('contact');
foreach ($contactNodes as $contactNode) {
# Check if we have found the relevant contact nodes
$type = $contactNode->getAttribute('type');
if ($type == "admin") {
$adminContactID = $contactNode->nodeValue;
} elseif ($type == "tech") {
$techContactID = $contactNode->nodeValue;
} elseif ($type == "billing") {
$billingContactID = $contactNode->nodeValue;
}
}
# Save contact details
$request = $client->request($xml = '
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0">
if (empty($adminContactID)) {
$values["error"] = "_SaveContactDetails/domain-info($domain): Admin contact info not available";
return $values;
}
if (empty($techContactID)) {
$values["error"] = "_SaveContactDetails/domain-info($domain): Technical contact info not available";
return $values;
}
if (empty($billingContactID)) {
$values["error"] = "_SaveContactDetails/domain-info($domain): Billing contact info not available";
return $values;
}
# Create contacts for use in our recreate below
$contacts['Registrant'] = $registrantContactDetails;
$contacts['Admin'] = $adminContactDetails;
$contacts['Technical'] = $technicalContactDetails;
$contacts['Billing'] = $billingContactDetails;
# We'll store the XML in here if we need to recreate contacts, this happens if admin/tech/billing are the same as
# registrant
$contactXML_chg = '';
$contactXML_rem = '';
$contactXML_add = '';
# Store errors we got
$errors = '';
# Check the contact ID's differ, if not, recreate the extra ones
if ($adminContactID == $registrantContactID || $adminContactID == $techContactID || $adminContactID == $billingContactID) {
$adminContact = __recreateContact($domain,$contacts,"Admin",$client);
# If there was an error return it
if (!isset($adminContact["error"])) {
$contactXML_rem .= '<domain:contact type="admin">'.$adminContactID.'</domain:contact>';
$adminContactID = $adminContact['contactid'];
$contactXML_add .= '<domain:contact type="admin">'.$adminContactID.'</domain:contact>';
} else {
$errors .= $adminContact["error"];
}
} else {
$values = __saveContact($adminContactID,$contacts,"Admin",$client);
# If there was an error return it
if (isset($values["error"])) {
$errors .= $values["error"];
}
}
if ($techContactID == $registrantContactID || $techContactID == $adminContactID || $techContactID == $billingContactID) {
$techContact = __recreateContact($domain,$contacts,"Technical",$client);
# If there was an error return it
if (!isset($techContact["error"])) {
$contactXML_rem .= '<domain:contact type="tech">'.$techContactID.'</domain:contact>';
$techContactID = $techContact['contactid'];
$contactXML_add .= '<domain:contact type="tech">'.$techContactID.'</domain:contact>';
} else {
$errors .= $adminContact["error"];
}
} else {
$values = __saveContact($techContactID,$contacts,"Technical",$client);
# If there was an error return it
if (isset($values["error"])) {
$errors .= $values["error"];
}
}
if ($billingContactID == $registrantContactID || $billingContactID == $adminContactID || $billingContactID == $techContactID) {
$billingContact = __recreateContact($domain,$contacts,"Billing",$client);
# If there was an error return it
if (!isset($billingContact["error"])) {
$contactXML_rem .= '<domain:contact type="billing">'.$billingContactID.'</domain:contact>';
$billingContactID = $billingContact['contactid'];
$contactXML_add .= '<domain:contact type="billing">'.$billingContactID.'</domain:contact>';
} else {
$errors .= $billingContact["error"];
}
} else {
$values = __saveContact($billingContactID,$contacts,"Billing",$client);
# If there was an error return it
if (isset($values["error"])) {
$errors .= $values["error"];
}
}
# Save registrant
$values = __saveContact($registrantContactID,$contacts,"Registrant",$client);
# If there was an error return it
if (isset($values["error"])) {
$errors .= $values["error"];
}
$contactXML_chg .= '<domain:registrant>'.$registrantContactID.'</domain:registrant>';
# Build the XML for the updates we need to do
$contactXML = "";
if (!empty($contactXML_add)) {
$contactXML .= '<domain:add>'.$contactXML_add.'</domain:add>';
}
if (!empty($contactXML_rem)) {
$contactXML .= '<domain:rem>'.$contactXML_rem.'</domain:rem>';
}
if (!empty($contactXML_chg)) {
$contactXML .= '<domain:chg>'.$contactXML_chg.'</domain:chg>';
}
# Check if we need to do a contact ID update
if (!empty($contactXML)) {
# Update domain contacts if any changed
$request = $client->request($xml = '
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xmlns:cozadomain="http://co.za/epp/extensions/cozadomain-1-0"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<epp:command>
<epp:update>
<contact:update>
<contact:id>'.$registrant.'</contact:id>
<contact:chg>
<contact:postalInfo type="loc">
<contact:name>'.$registrant_name.'</contact:name>
<contact:org>'.$registrant_org.'</contact:org>
<contact:addr>
<contact:street>'.$registrant_address1.'</contact:street>
<contact:street>'.$registrant_address2.'</contact:street>
<contact:city>'.$registrant_town.'</contact:city>
<contact:sp>'.$registrant_state.'</contact:sp>
<contact:pc>'.$registrant_zipcode.'</contact:pc>
<contact:cc>'.$registrant_countrycode.'</contact:cc>
</contact:addr>
</contact:postalInfo>
<contact:voice>'.$registrant_phone.'</contact:voice>
<contact:fax></contact:fax>
<contact:email>'.$registrant_email.'</contact:email>
</contact:chg>
</contact:update>
<domain:update>
<domain:name>'.$domain.'</domain:name>
'.$contactXML.'
</domain:update>
</epp:update>
</epp:command>
</epp:epp>
');
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', 'SaveContactDetails', $xml, $request);
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', 'SaveContactDetails', $xml, $request);
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1001') {
$errors .= "_SaveContactDetails/domain-info($domain): Code (".$coderes.") ".$msg;
}
}
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1001') {
$values["error"] = "SaveContactDetails/contact-update($registrant): Code ($coderes) $msg";
return $values;
# Check what we're going to return
unset($values);
if ($errors) {
$values["error"] = $errors;
} else {
$values['msg'] = "Contact details saved.";
}
$values["status"] = $msg;
return $values;
} catch (Exception $e) {
$values["error"] = 'SaveContactDetails/EPP: '.$e->getMessage();
......@@ -974,6 +1333,7 @@ function cozaepp_GetEPPCode($params) {
$testmode = $params["TestMode"];
$sld = $params["sld"];
$tld = $params["tld"];
$domain = strtolower("$sld.$tld");
$values["eppcode"] = '';
......@@ -992,13 +1352,14 @@ function cozaepp_RegisterNameserver($params) {
$testmode = $params["TestMode"];
$sld = $params["sld"];
$tld = $params["tld"];
$domain = strtolower("$sld.$tld");
$nameserver = $params["nameserver"];
$ipaddress = $params["ipaddress"];
# Grab client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Register nameserver
$request = $client->request($xml = '
......@@ -1006,7 +1367,7 @@ function cozaepp_RegisterNameserver($params) {
<epp:command>
<epp:update>
<domain:update>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
<domain:add>
<domain:ns>
<domain:hostAttr>
......@@ -1030,7 +1391,7 @@ function cozaepp_RegisterNameserver($params) {
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check if result is ok
if($coderes != '1001') {
$values["error"] = "RegisterNameserver/domain-update($sld.$tld): Code ($coderes) $msg";
$values["error"] = "RegisterNameserver/domain-update($domain): Code ($coderes) $msg";
return $values;
}
......@@ -1055,6 +1416,7 @@ function cozaepp_ModifyNameserver($params) {
$testmode = $params["TestMode"];
$tld = $params["tld"];
$sld = $params["sld"];
$domain = strtolower("$sld.$tld");
$nameserver = $params["nameserver"];
$currentipaddress = $params["currentipaddress"];
$newipaddress = $params["newipaddress"];
......@@ -1062,7 +1424,7 @@ function cozaepp_ModifyNameserver($params) {
# Grab client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Modify nameserver
$request = $client->request($xml = '
......@@ -1070,7 +1432,7 @@ function cozaepp_ModifyNameserver($params) {
<epp:command>
<epp:update>
<domain:update>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
<domain:add>
<domain:ns>
<domain:hostAttr>
......@@ -1094,7 +1456,7 @@ function cozaepp_ModifyNameserver($params) {
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check if result is ok
if($coderes != '1001') {
$values["error"] = "ModifyNameserver/domain-update($sld.$tld): Code ($coderes) $msg";
$values["error"] = "ModifyNameserver/domain-update($domain): Code ($coderes) $msg";
return $values;
}
......@@ -1117,12 +1479,13 @@ function cozaepp_DeleteNameserver($params) {
$testmode = $params["TestMode"];
$tld = $params["tld"];
$sld = $params["sld"];
$domain = strtolower("$sld.$tld");
$nameserver = $params["nameserver"];
# Grab client instance
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# If we were given hostname. blow away all of the stuff behind it and allow us to remove hostname
$nameserver = preg_replace('/\.\.\S+/','',$nameserver);
......@@ -1133,7 +1496,7 @@ function cozaepp_DeleteNameserver($params) {
<epp:command>
<epp:update>
<domain:update>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
<domain:rem>
<domain:ns>
<domain:hostAttr>
......@@ -1156,7 +1519,7 @@ function cozaepp_DeleteNameserver($params) {
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check if result is ok
if($coderes != '1001') {
$values["error"] = "DeleteNameserver/domain-update($sld.$tld): Code ($coderes) $msg";
$values["error"] = "DeleteNameserver/domain-update($domain): Code ($coderes) $msg";
return $values;
}
......@@ -1171,6 +1534,7 @@ function cozaepp_DeleteNameserver($params) {
}
# Function to return meaningful message from response code
function _cozaepp_message($code) {
......@@ -1179,6 +1543,7 @@ function _cozaepp_message($code) {
}
# Ack a POLL message
function _cozaepp_ackpoll($client,$msgid) {
# Ack poll message
......@@ -1199,13 +1564,57 @@ function _cozaepp_ackpoll($client,$msgid) {
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
# Check result
if($coderes != '1301' && $coderes != '1300') {
if($coderes != '1301' && $coderes != '1300' && $coderes != 1000) {
throw new Exception("ackpoll/poll-ack($id): Code ($coderes) $msg");
}
}
# Helper function to centrally provide data and information about different SLDs.
function _cozaepp_SldLookup($domain) {
# TLD server data provided by ZACR
$tldservers = array(
'co.za' => array(
'fqdn' => 'epp.coza.net.za',
'port' => 3121,
'additional_contacts' => true
),
'org.za' => array(
'fqdn' => 'org-epp.registry.net.za',
'port' => 3121,
'additional_contacts' => true
),
'web.za' => array(
'fqdn' => 'web-epp.registry.net.za',
'port' => 3121,
'additional_contacts' => true
),
'net.za' => array(
'fqdn' => 'net-epp.registry.net.za',
'port' => 3121,
'additional_contacts' => true
),
);
if (!is_null($domain)) {
foreach ($tldservers as $tld => $data) {
if (preg_match("/$tld$/i", $domain)) {
return $data;
}
}
throw new Exception('SLD lookup failed to find: '.$domain);
} else { # defaults to co.za server.
return $tldservers['co.za'];
}
}
# Function to create internal COZA EPP request
function _cozaepp_Client() {
function _cozaepp_Client($domain=null) {
# Setup include dir
$include_path = ROOTDIR . '/modules/registrars/cozaepp';
set_include_path($include_path . PATH_SEPARATOR . get_include_path());
......@@ -1215,13 +1624,14 @@ function _cozaepp_Client() {
# Grab module parameters
$params = getregistrarconfigoptions('cozaepp');
# Set server address and port based on parsed domain name
$_server = _cozaepp_SldLookup($domain);
# Check if module parameters are sane
if (empty($params['Username']) || empty($params['Password'])) {
throw new Exception('System configuration error(1), please contact your provider');
}
if ($params['Server'] != 'regphase3.dnservices.co.za' && $params['Server'] != 'epp.coza.net.za') {
throw new Exception('System configuration error(2), please contact your provider');
}
# Create SSL context
$context = stream_context_create();
......@@ -1243,7 +1653,7 @@ function _cozaepp_Client() {
$client = new Net_EPP_Client();
# Connect
$res = $client->connect($params['Server'], $params['Port'], 10, $use_ssl, $context);
$res = $client->connect($_server['fqdn'], $_server['port'], 10, $use_ssl, $context);
# Perform login
$request = $client->request($xml = '
......@@ -1269,11 +1679,14 @@ function _cozaepp_Client() {
return $client;
}
function cozaepp_TransferSync($params) {
$domainid = $params['domainid'];
$domain = $params['domain'];
$sld = $params['sld'];
$tld = $params['tld'];
$domain = strtolower("$sld.$tld");
$registrar = $params['registrar'];
$regperiod = $params['regperiod'];
$status = $params['status'];
......@@ -1285,7 +1698,7 @@ function cozaepp_TransferSync($params) {
# Grab domain info
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab domain info
$request = $client->request($xml = '
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
......@@ -1345,24 +1758,20 @@ function cozaepp_TransferSync($params) {
return $values;
}
function cozaepp_RecreateContact($params) {
# Grab variables
$tld = $params["tld"];
$sld = $params["sld"];
# Get client instance
try {
$client = _cozaepp_Client();
# Fetching contact details
$contact = _getContactDetails($sld . '.' . $tld, $client);
# If there was an error return it
if (isset($contact["error"])) {
return $contact;
function __recreateContact($domain,$contacts,$type,$client = null) {
# Get client instance
try {
if (!isset($client)) {
$client = _cozaepp_Client($domain);
}
# Check for available contact id
$registrant = _cozaepp_CheckContact($sld . '.' . $tld);
$contactID = _cozaepp_CheckContact($domain,$type);
# Generate a random password for the contact
$pw = substr(md5($domain . time() . rand(0, 1000000)), 0,15);
# Recreate contact
$request = $client->request($xml = '
......@@ -1371,24 +1780,24 @@ function cozaepp_RecreateContact($params) {
<epp:command>
<epp:create>
<contact:create xsi:schemaLocation="urn:ietf:params:xml:ns:contact-1.0 contact-1.0.xsd">
<contact:id>'.$registrant.'</contact:id>
<contact:id>'.$contactID.'</contact:id>
<contact:postalInfo type="loc">
<contact:name>'.$contact["Registrant"]["Contact Name"].'</contact:name>
<contact:org>'.$contact["Registrant"]["Organisation"].'</contact:org>
<contact:name>'.$contacts[$type]["Contact Name"].'</contact:name>
<contact:org>'.$contacts[$type]["Organisation"].'</contact:org>
<contact:addr>
<contact:street>'.$contact["Registrant"]["Address line 1"].'</contact:street>
<contact:street>'.$contact["Registrant"]["Address line 2"].'</contact:street>
<contact:city>'.$contact["Registrant"]["TownCity"].'</contact:city>
<contact:sp>'.$contact["Registrant"]["State"].'</contact:sp>
<contact:pc>'.$contact["Registrant"]["Zip code"].'</contact:pc>
<contact:cc>'.$contact["Registrant"]["Country Code"].'</contact:cc>
<contact:street>'.$contacts[$type]["Address line 1"].'</contact:street>
<contact:street>'.$contacts[$type]["Address line 2"].'</contact:street>
<contact:city>'.$contacts[$type]["TownCity"].'</contact:city>
<contact:sp>'.$contacts[$type]["State"].'</contact:sp>
<contact:pc>'.$contacts[$type]["Zip code"].'</contact:pc>
<contact:cc>'.$contacts[$type]["Country Code"].'</contact:cc>
</contact:addr>
</contact:postalInfo>
<contact:voice>'.$contact["Registrant"]["Phone"].'</contact:voice>
<contact:voice>'.$contacts[$type]["Phone"].'</contact:voice>
<contact:fax></contact:fax>
<contact:email>'.$contact["Registrant"]["Email"].'</contact:email>
<contact:email>'.$contacts[$type]["Email"].'</contact:email>
<contact:authInfo>
<contact:pw>AxA8AjXbAH'.rand().rand().'</contact:pw>
<contact:pw>'.$pw.'</contact:pw>
</contact:authInfo>
</contact:create>
</epp:create>
......@@ -1399,16 +1808,70 @@ function cozaepp_RecreateContact($params) {
# Parse XML result
$doc= new DOMDocument();
$doc->loadXML($request);
logModuleCall('Cozaepp', 'RecreateContact', $xml, $request);
logModuleCall('Cozaepp', '__recreateContact', $xml, $request);
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1000') {
$values["error"] = "RecreateContact/contact-create($registrant): Code ($coderes) $msg";
$values["error"] = "__recreateContact/contact-create($contactID:$type): Code ($coderes) $msg";
return $values;
}
$values["status"] = $msg;
$values["contactid"] = $contactID;
return $values;
} catch (Exception $e) {
$values["error"] = '__recreateContact/EPP: '.$e->getMessage();
return $values;
}
}
function cozaepp_RecreateContact($params) {
# Grab variables
$tld = $params["tld"];
$sld = $params["sld"];
$domain = strtolower("$sld.$tld");
# Get client instance
try {
$client = _cozaepp_Client($domain);
# Fetching contact details
$contacts = _getContactDetails($domain, $client);
# If there was an error return it
if (isset($contacts["error"])) {
return $contacts;
}
# Create contacts
$registrantContact = __recreateContact($domain,$contacts,"Registrant",$client);
# If there was an error return it
if (isset($registrantContact["error"])) {
return $registrantContact;
}
$registrantContactID = $registrantContact['contactid'];
$adminContact = __recreateContact($domain,$contacts,"Admin",$client);
# If there was an error return it
if (isset($adminContact["error"])) {
return $adminContact;
}
$adminContactID = $adminContact['contactid'];
$techContact = __recreateContact($domain,$contacts,"Technical",$client);
# If there was an error return it
if (isset($techContact["error"])) {
return $techContact;
}
$techContactID = $techContact['contactid'];
$billingContact = __recreateContact($domain,$contacts,"Billing",$client);
# If there was an error return it
if (isset($billingContact["error"])) {
return $billingContact;
}
$billingContactID = $billingContact['contactid'];
# Update domain registrant
$request = $client->request($xml = '
......@@ -1416,9 +1879,12 @@ function cozaepp_RecreateContact($params) {
<epp:command>
<epp:update>
<domain:update>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
<domain:chg>
<domain:registrant>'.$registrant.'</domain:registrant>
<domain:registrant>'.$registrantContactID.'</domain:registrant>
<domain:admin>'.$adminContactID.'</domain:admin>
<domain:tech>'.$techContactID.'</domain:tech>
<domain:billing>'.$billingContactID.'</domain:billing>
</domain:chg>
</domain:update>
</epp:update>
......@@ -1433,7 +1899,7 @@ function cozaepp_RecreateContact($params) {
$coderes = $doc->getElementsByTagName('result')->item(0)->getAttribute('code');
$msg = $doc->getElementsByTagName('msg')->item(0)->nodeValue;
if($coderes != '1001') {
$values["error"] = "RecreateContact/domain-info($sld.$tld): Code (".$coderes.") ".$msg;
$values["error"] = "RecreateContact/domain-info($domain): Code (".$coderes.") ".$msg;
return $values;
}
......@@ -1447,11 +1913,14 @@ function cozaepp_RecreateContact($params) {
return $values;
}
function cozaepp_Sync($params) {
$domainid = $params['domainid'];
$domain = $params['domain'];
$sld = $params['sld'];
$tld = $params['tld'];
$domain = strtolower("$sld.$tld");
$registrar = $params['registrar'];
$regperiod = $params['regperiod'];
$status = $params['status'];
......@@ -1463,7 +1932,7 @@ function cozaepp_Sync($params) {
# Grab domain info
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab domain info
$request = $client->request($xml = '
<epp:epp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:epp="urn:ietf:params:xml:ns:epp-1.0"
......@@ -1527,6 +1996,8 @@ function cozaepp_Sync($params) {
if ($statusres == "ok") {
$values['active'] = true;
} elseif ($statusres == "pendingUpdate") {
} elseif ($statusres == "serverHold") {
} elseif ($statusres == "expired" || $statusres == "pendingDelete" || $statusres == "inactive") {
......@@ -1547,13 +2018,15 @@ function cozaepp_Sync($params) {
}
function cozaepp_RequestDelete($params) {
$sld = $params['sld'];
$tld = $params['tld'];
$domain = strtolower("$sld.$tld");
# Grab domain info
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab domain info
$request = $client->request($xml = '
......@@ -1562,7 +2035,7 @@ function cozaepp_RequestDelete($params) {
<epp:command>
<epp:delete>
<domain:delete xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
</domain:delete>
</epp:delete>
</epp:command>
......@@ -1579,7 +2052,7 @@ function cozaepp_RequestDelete($params) {
# Check result
if($coderes != '1001') {
$values['error'] = 'RequestDelete/domain-info('.$sld.'.'.$tld.'): Code('._cozaepp_message($coderes).") $msg";
$values['error'] = 'RequestDelete/domain-info('.$domain.'): Code('._cozaepp_message($coderes).") $msg";
return $values;
}
......@@ -1593,13 +2066,16 @@ function cozaepp_RequestDelete($params) {
return $values;
}
function cozaepp_ApproveTransfer($params) {
$sld = $params['sld'];
$tld = $params['tld'];
$domain = strtolower("$sld.$tld");
# Grab domain info
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab domain info
$request = $client->request($xml = '
......@@ -1607,7 +2083,7 @@ function cozaepp_ApproveTransfer($params) {
<epp:command>
<epp:transfer op="approve">
<domain:transfer>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
<domain:name>'.$domain.'</domain:name>
</domain:transfer>
</epp:transfer>
</epp:command>
......@@ -1624,7 +2100,7 @@ function cozaepp_ApproveTransfer($params) {
# Check result
if($coderes != '1000') {
$values['error'] = 'ApproveTransfer/domain-info('.$sld.'.'.$tld.'): Code('._cozaepp_message($coderes).") $msg";
$values['error'] = 'ApproveTransfer/domain-info('.$domain.'): Code('._cozaepp_message($coderes).") $msg";
return $values;
}
......@@ -1639,24 +2115,26 @@ function cozaepp_ApproveTransfer($params) {
}
function cozaepp_CancelTransferRequest($params) {
$sld = $params['sld'];
$tld = $params['tld'];
$domain = strtolower("$sld.$tld");
# Grab domain info
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab domain info
$request = $client->request($xml = '
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<epp:command>
<epp:transfer op="cancel">
<domain:transfer>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
</domain:transfer>
</epp:transfer>
</epp:command>
<epp:command>
<epp:transfer op="cancel">
<domain:transfer>
<domain:name>'.$domain.'</domain:name>
</domain:transfer>
</epp:transfer>
</epp:command>
</epp:epp>
');
......@@ -1670,7 +2148,7 @@ function cozaepp_CancelTransferRequest($params) {
# Check result
if($coderes != '1000') {
$values['error'] = 'CancelTransferRequest/domain-info('.$sld.'.'.$tld.'): Code('._cozaepp_message($coderes).") $msg";
$values['error'] = 'CancelTransferRequest/domain-info('.$domain.'): Code('._cozaepp_message($coderes).") $msg";
return $values;
}
......@@ -1685,24 +2163,26 @@ function cozaepp_CancelTransferRequest($params) {
}
function cozaepp_RejectTransfer($params) {
$sld = $params['sld'];
$tld = $params['tld'];
$domain = strtolower("$sld.$tld");
# Grab domain info
try {
$client = _cozaepp_Client();
$client = _cozaepp_Client($domain);
# Grab domain info
$request = $client->request($xml = '
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<epp:command>
<epp:transfer op="reject">
<domain:transfer>
<domain:name>'.$sld.'.'.$tld.'</domain:name>
</domain:transfer>
</epp:transfer>
</epp:command>
<epp:command>
<epp:transfer op="reject">
<domain:transfer>
<domain:name>'.$domain.'</domain:name>
</domain:transfer>
</epp:transfer>
</epp:command>
</epp:epp>
');
......@@ -1716,7 +2196,7 @@ function cozaepp_RejectTransfer($params) {
# Check result
if($coderes != '1000') {
$values['error'] = 'RejectTransfer/domain-info('.$sld.'.'.$tld.'): Code('._cozaepp_message($coderes).") $msg";
$values['error'] = 'RejectTransfer/domain-info('.$domain.'): Code('._cozaepp_message($coderes).") $msg";
return $values;
}
......
<?
# Copyright (c) 2012-2013, AllWorldIT
<?php
# Copyright (c) 2012-2015, AllWorldIT
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -38,7 +38,7 @@
# This file brings in a few constants we need
require_once dirname(__FILE__) . '/../../../dbconnect.php';
require_once dirname(__FILE__) . '/../../../init.php';
# Setup include dir
$include_path = ROOTDIR . '/modules/registrars/cozaepp';
set_include_path($include_path . PATH_SEPARATOR . get_include_path());
......
<?php
# Copyright (c) 2012, AllWorldIT
#
# Copyright (c) 2012-2015, AllWorldIT
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
......@@ -18,21 +18,21 @@
# Official Website:
# http://devlabs.linuxassist.net/projects/whmcs-coza-epp
# Lead developer:
# Lead developer:
# Nigel Kukard <nkukard@lbsd.net>
# ! ! P L E A S E N O T E ! !
# * If you make changes to this file, please consider contributing
# * If you make changes to this file, please consider contributing
# anything useful back to the community. Don't be a sour prick.
# * If you find this module useful please consider making a
# * If you find this module useful please consider making a
# donation to support modules like this.
# WHMCS hosting, theming, module development, payment gateway
# integration, customizations and consulting all available from
# WHMCS hosting, theming, module development, payment gateway
# integration, customizations and consulting all available from
# http://allworldit.com
......@@ -60,7 +60,7 @@ function widget_cozaepp_balance($vars) {
$client = _cozaepp_Client();
$output = $client->request('
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0" xmlns:contact="urn:ietf:params:xml:ns:contact-1.0"
xmlns:cozacontact="http://co.za/epp/extensions/cozacontact-1-0">
<epp:command>
<epp:info>
......@@ -96,4 +96,3 @@ function widget_cozaepp_balance($vars) {
add_hook("AdminHomeWidgets",1,"widget_cozaepp_balance");
?>