<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

// TODO: PUNY encoding

require_once dirname(__FILE__).'/../../../classes/error_ce.php';
require_once dirname(__FILE__).'/../../../classes/observable.php';
require_once dirname(__FILE__).'/../../../encrypted/commonfunctions.php';
require_once dirname(__FILE__).'/../../../common/xmlFunctions.php';

// insert credentials and uncomment to update registrars table
//$gSettingsArray['plugin_enom_Use testing server'] = true;
//_plugin_enom_updateRegistrarsTable(array('uid' => '', 'pw' => ''));

function plugin_enom_variables()
{
    $variables = array(
       'Plugin Name' => array (
            'type'          => 'hidden', 
            'description'   => 'How CE sees this plugin (not to be confused with the Signup Name)',
            'value'         => 'Enom',
         ),
        'Use Enom to check and register domains' => array(
            'type'          => 'yesno',
            'description'  => "If you don't use any registrar, the domain check is done with whois.",
            'value'         => 0,
        ),
        'Use testing server' => array(
            'type'          => 'yesno',
            'description'   => 'Select Yes if you wish to use Enom\'s testing environment, so that transactions are not actually made. For this to work, you must first register you server\'s ip in Enom\'s testing environment, and your server\'s name servers must be registered there as well.',
            'value'         => 0,
        ),
        'Login' => array(
            'type'          => 'text',
            'description'   => 'Enter your username for your Enom reseller account.',
        ),
        'Password'  => array(
            'type'          => 'password',
            'description'   => 'Enter the password for your Enom reseller account.',
        ),
    );

    return $variables;
}

function plugin_enom_getSupportedTLDs($params)
{
    $arguments = array(
        'command'       => 'gettldlist',
        'uid'           => $params['Login'],
        'pw'            => $params['Password'],
    );
    $response = _plugin_enom_make_request($params, $arguments);

    if (!is_array($response)) return false;

    $err = $response['interface-response']['#']['ErrCount'][0]['#'];
    if ($err > 0) {
        return new Error_CE(130, $response['interface-response']['#']['errors'][0]['#']['Err1'][0]['#']);
    }

    $tlds = array();
    foreach ($response['interface-response']['#']['tldlist'][0]['#']['tld'] as $value) {
        $tlds[] = $value['#']['tld'][0]['#'];
    }

    return $tlds;
}

// returns array(code [,message]), where code is:
// 0:       Domain available
// 1:       Domain already registered
// 2:       Registrar Error, domain extension not recognized or supported
// 3:       Domain invalid
// 5:       Could not contact registry to lookup domain
function plugin_enom_check_domain($params)
{
    $arguments = array(
        'command'       => 'check',
        'uid'           => $params['Login'],
        'pw'            => $params['Password'],
        'tld'           => $params['tld'],
        'sld'           => $params['sld'],
    );
    $response = _plugin_enom_make_request($params, $arguments);

    if (!$response) return array(5);

    $err = $response['interface-response']['#']['ErrCount'][0]['#'];
    if ($err > 0) return array(5, $response['interface-response']['#']['errors'][0]['#']['Err1'][0]['#']);

    $RRPCode = $response['interface-response']['#']['RRPCode'][0]['#'];
    if ($RRPCode == 210) return array(0);
    if ($RRPCode == 211) return array(1);
    if ($RRPCode == 723) return array(2);
    else return array(1);
}


// possible return values: array(code [,message])
// -1:  error trying to purchase domain
// 0:   domain not available
// >0:  Operation successfull, returns orderid
function plugin_enom_register_domain($params)
{
    $arguments = array(
        'command'                       => 'purchase',
        'uid'                           => $params['Login'],
        'pw'                            => $params['Password'],
        'tld'                           => $params['tld'],
        'sld'                           => $params['sld'],
        'NumYears'                      => $params['NumYears'],
        'Renewname'                     => '1', // automatically renew domain
        'RegistrantOrganizationName'    => $params['RegistrantOrganizationName'],
        'RegistrantFirstName'           => $params['RegistrantFirstName'],
        'RegistrantLastName'            => $params['RegistrantLastName'],
        'RegistrantEmailAddress'        => $params['RegistrantEmailAddress'],
        'RegistrantPhone'               => _plugin_enom_validatePhone($params['RegistrantPhone'], $params['RegistrantCountry']),
        'RegistrantAddress1'            => $params['RegistrantAddress1'],
        'RegistrantCity'                => $params['RegistrantCity'],
        //'RegistrantStateProvinceChoice' => $params['RegistrantStateProvinceChoice'],
        'RegistrantStateProvince'       => $params['RegistrantStateProvince'],
        'RegistrantPostalCode'          => $params['RegistrantPostalCode'],
        'RegistrantCountry'             => $params['RegistrantCountry'],
    );

    if (is_array($params['ExtendedAttributes'])) {
        foreach ($params['ExtendedAttributes'] as $name => $value) {
            $arguments[$name] = $value;
        }
    }

    if (isset($params['NS1'])) {
        // maximum 12 name servers are allowed by Enom
        for ($i = 1; $i <= 12; $i++) {
            if (isset($params["NS$i"])) {
                $arguments["NS$i"] = $params["NS$i"]['hostname'];
            } else {
                break;
            }
        }
    } else {
        // use Enom's default name servers
        $arguments['usedns'] = 'default';
    }

    $response = _plugin_enom_make_request($params, $arguments);

    $err = $response['interface-response']['#']['ErrCount'][0]['#'];
    if (isset($response['interface-response']['#']['RRPCode'][0]['#'])) {
        $RRPCode = $response['interface-response']['#']['RRPCode'][0]['#'];
    } else {
        $RRPCode = '';
    }
    if ($err >0) {
        switch ($RRPCode) {
            case 540:
                return array(0);
                break;
            default:
                $messages = array();
                for ($i = 1; $i <= $err; $i++) {
                    $messages[] = $response['interface-response']['#']['errors'][0]['#']["Err$i"][0]['#'];
                }
                if (isset($response['interface-response']['#']['MinPeriod'][0]['#'])) {
                    $messages[] = "Minimum registration period is {$response['interface-response']['#']['MinPeriod'][0]['#']} year(s)";
                }
                if (isset($response['interface-response']['#']['MaxPeriod'][0]['#'])) {
                    $messages[] = "Maximum registration period is {$response['interface-response']['#']['MaxPeriod'][0]['#']} year(s)";
                }
                return array(-1, $messages);
        }
    }

    if ($RRPCode == 200 || $RRPCode == 1300) {
        $order_id = $response['interface-response']['#']['OrderID'][0]['#'];
        return array($order_id);
    }
}

function plugin_enom_disable_renewal($params)
{
    $arguments = array(
        'command'   => 'SetRenew',
        'uid'       => $params['Login'],
        'pw'        => $params['Password'],
        'tld'       => $params['tld'],
        'sld'       => $params['sld'],
        'RenewFlag' => '0',
    );

    $response = _plugin_enom_make_request($params, $arguments);

    $err = $response['interface-response']['#']['ErrCount'][0]['#'];
    if ($err >0) {
        $messages = array();
        for ($i = 1; $i <= $err; $i++) {
            $messages[] = $response['interface-response']['#']['errors'][0]['#']["Err$i"][0]['#'];
        }
        return array(-1, $messages);
    }

    return array(1);
}

// called from outside CE once in a while
function _plugin_enom_updateRegistrarsTable($params)
{
    require_once dirname(__FILE__) . '/../../../config.php';
    $connection = mysql_connect($hostname, $dbuser, $dbpass) or die("Couldn't establish database connection");
    mysql_select_db($database, $connection) or die("Can not select database: $database");

    $supportedTLDs = plugin_enom_getSupportedTLDs($params);
    echo "This plugin supports ".count($supportedTLDs)." tlds\n\n";
    foreach ($supportedTLDs as $tld) {
        echo "Checking $tld\n";
        $arguments = array(
            'command'   => 'getExtAttributes',
            'uid'       => $params['Login'],
            'pw'        => $params['Password'],
            'tld'       => $tld,
        );
        $response = _plugin_enom_make_request($params, $arguments);
        $err = $response['interface-response']['#']['ErrCount'][0]['#'];
        if ($err > 0) return array(5, $response['interface-response']['#']['errors'][0]['#']['Err1'][0]['#']);

        if (!isset($response['interface-response']['#']['Attributes'][0]['#']['Attribute'])) {
            continue;
        }

        $extraAttributes = array();
        foreach ($response['interface-response']['#']['Attributes'][0]['#']['Attribute'] as $attribute) {
            if ($attribute['#']['Required'][0]['#'] == '0') {
                continue;
            }
            if ($attribute['#']['Description'][0]['#'] == 'Country') {
                // We're already sending the country in another field
                continue;
            }
            $attributeName = $attribute['#']['Name'][0]['#'];
            $extraAttributes[$attributeName]['ID']           = $attribute['#']['ID'][0]['#'];
            $extraAttributes[$attributeName]['description']  = $attribute['#']['Description'][0]['#'];

            $extraAttributes[$attributeName]['options'] = array();
            if (is_array($attribute['#']['Options'][0]['#']['Option'])) {
                foreach ($attribute['#']['Options'][0]['#']['Option'] as $option) {
                    $extraAttributes[$attributeName]['options'][$option['#']['Title'][0]['#']] = array(
                                                            'description'  => $option['#']['Description'][0]['#'],
                                                            'value'        => $option['#']['Value'][0]['#'],
                                                        );
                    if (isset($option['#']['Requires'])) {
                        $extraAttributes[$attributeName]['options'][$option['#']['Title'][0]['#']]['requires'] = array();
                        foreach ($option['#']['Requires'] as $requirement) {
                            $extraAttributes[$attributeName]['options'][$option['#']['Title'][0]['#']]['requires'][] = $requirement['#']['Attribute'][0]['#']['ID'][0]['#'];
                        }
                    }
                }
            }
        }

        //print_r($extraAttributes);
        if (!$extraAttributes) {
            continue;
        }
        $extraAttributes = serialize($extraAttributes);
        $extraAttributes = mysql_real_escape_string(($extraAttributes));
        $query = "REPLACE INTO registrars SET plugin='enom', tld='$tld', extra_attributes='$extraAttributes'";
        mysql_query($query) or die("Error in query $query");
    }

    return $extraAttributes;
}

function _plugin_enom_make_request($params, $arguments)
{
    global $gSettingsArray;

    // default paramters
    if (!isset($params['secure'])) $params['secure'] = true;
    if (!isset($params['test'])) $params['test'] = false;

    require_once dirname(__FILE__).'/../../../common/xmlFunctions.php';

    if ($params['secure']) $request = 'https://';
    else $request= 'http://';

    if (@$gSettingsArray['plugin_enom_Use testing server']) $request .= 'resellertest.enom.com/interface.asp';
    else $request .= 'reseller.enom.com/interface.asp';

    $arguments['responsetype'] = 'XML';

    $i = 0; 
    foreach ($arguments as $name => $value) {
        $value = urlencode($value);
        if (!$i) $request .= "?$name=$value";
        else $request .= "&$name=$value";
        $i++;
    }

    if ($params['test']) echo "$request\n";

    //echo "$request\n";
    // certificate validation doesn't work well under windows
    $response = curlRequest($request, false, false, true);
    //echo $response;

    if (!$response) return false;   // don't want xmlize an empty array

    $response = xmlize($response);

    return $response;
}

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

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

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

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

?>
