<?php
/**
 * OpenSRS Domain Registrar Plugin
 *
 * @category Plugin
 * @package  ClientExec
 * @author   Jason Yates <jason@clientexec.com>
 * @license  ClientExec License
 * @version  2
 * @link     http://www.clientexec.com
 */

require_once 'modules/admin/models/RegistrarPlugin.php';
require_once dirname(__FILE__).'/class.opensrs.php';

/**
 * PluginOpensrs RegistrarPlugin Class
 *
 * VALID FUNCTIONS
 * getVariables - Config vars for plugin
 * checkDomain - check if given domain is available
 * registerDomain - register a given domain with OpenSRS
 * setAutorenew - change the Auto Renew status of a domain
 *
 * TODO FUNCTIONS
 *
 * @category Plugin
 * @package  ClientExec
 * @author   Jason Yates <jason@clientexec.com>
 * @license  ClientExec License
 * @version  2
 * @link     http://www.clientexec.com
 */
class PluginOpensrs extends RegistrarPlugin
{

    var $liveHost = "rr-n1-tor.opensrs.net";
    var $testHost = "horizon.opensrs.net";
    var $connPort = "55443";

    /**
     * Function to return a list of configurable variables for the class
     *
     * @return array
     */
    function getVariables()
    {
        $variables = array(
                /*T*/'Plugin Name'/*/T*/ => array (
                        'type'          =>'hidden',
                        'description'   =>/*T*/'How CE sees this plugin (not to be confused with the Signup Name)'/*/T*/,
                        'value'         =>/*T*/'OpenSRS'/*/T*/
                ),
                /*T*/'Use testing server'/*/T*/ => array(
                        'type'          =>'yesno',
                        'description'   =>/*T*/'Select Yes if you wish to use OpenSRS\'s testing environment, so that transactions are not actually made.'/*/T*/,
                        'value'         => 0
                ),
                /*T*/'Username'/*/T*/ => array(
                        'type'          => 'text',
                        'description'   => /*T*/'Enter your username for your OpenSRS reseller account.'/*/T*/,
                        'value'         => '',
                ),
                /*T*/'Private Key'/*/T*/  => array(
                        'type'          => 'text',
                        'description'   => /*T*/'Enter your OpenSRS reseller private key.'/*/T*/,
                        'value'         => '',
                )
        );

        return $variables;
    }

    /**
     * Function to check if the given domain is available to be registered.
     *
     * This will eventually allow support for the name lookup command to return an array of available domains by suggestion
     *
     * @return array
     */
    function checkDomain($params)
    {
        // Calculate the host
        $host = ($params['Use testing server'])? $this->testHost:$this->liveHost;

        // Start the connection
        $opensrs = new OpenSRS($host, $this->connPort, $params['Username'], $params['Private Key'], $this->logger);

        // Perform the lookup
        $return = $opensrs->lookup_domain(strtolower($params['sld']), strtolower($params['tld']));

        // Check the reply
        if ($return == null) {
            $this->logger->log(4, "OpenSRS Error: Ensure port 55443 is open and PHP is compiled with OpenSSL.");
            return array(5);
        }

        // Check we had a succcess code
        if ($return['status']['response_code'] != 200) {
            $this->logger->log(4, "OpenSRS Lookup Failed: ".$return['status']['response_text']);
            return array(5);
        }

        // FOR NOW MANAULLY USE THE FIRST DOMAIN. Expand to return multiple in the future
        $available = $return['result'][0]['status'];
        if ($available == 'available') return array(0);
        if ($available == 'taken' || $available == 'justsold') return array (1);
        return array(5);
    }

    /**
     * Function to register the given domain. This needs tidying up
     *
     * @return array
     */
    function registerDomain($params)
    {
        if ($params['Use testing server']) {
            $host = 'horizon.opensrs.net';
            $params['NS1']['hostname'] = "default.opensrs.org";
            $params['NS2']['hostname'] = "default1.opensrs.org";
            $params['Custom NS'] = 1;
            for ($i = 3; $i <= 12; $i++) {
                unset($params['NS'.$i]);
            }
        } else {
            $host = 'rr-n1-tor.opensrs.net';
            if (isset($params['NS1'])) {
                $params['Custom NS'] = 1;
            } else {
                $params['Custom NS'] = 0;
            }
        }

        if(!@$params['renewname'] == 0) {
            $params['renewname'] = 1;
        }

        $opensrs = new OpenSRS($host, $this->connPort,
                $params['Username'],
                $params['Private Key'],
                $this->logger);


        $params['domain'] = strtolower($params['sld'].".".$params['tld']);
        $params['RegistrantPhone'] = $this->_plugin_opensrs_validatePhone($params['RegistrantPhone'],$params['RegistrantCountry']);
        if ($params['RegistrantOrganizationName'] == "") $params['RegistrantOrganizationName'] = $params['RegistrantFirstName']." ".$params['RegistrantLastName'];

        // Process the extended attributes
        if (is_array($params['ExtendedAttributes'])) {
            foreach ($params['ExtendedAttributes'] as $name => $value) {
                $params[$name] = $value;
            }
        }

        /* Grab some information that isn't passed by default */
        $query = "SELECT id from customuserfields where type='8'";
        $result = $this->db->query($query);
        list($fieldid) = $result->fetch();

        $query = "SELECT id FROM users WHERE email=?";
        $result = $this->db->query($query, $params['RegistrantEmailAddress']);
        list($userid) = $result->fetch();

        $query = "SELECT value FROM user_customuserfields WHERE customid=? AND userid=?";
        $result = $this->db->query($query, $fieldid, $userid);
        list($lang) = $result->fetch();
        if (strtolower($lang) == 'french') $params['RegistrantLanguage'] = 'FR';
        else $params['RegistrantLanguage'] = 'EN';


        $return = $opensrs->register_domain($params);

        if ($return == null) {
            $this->logger->log(4, "OpenSRS Error: Ensure port 55443 is open and PHP is compiled with OpenSSL.");
            return array(-1, array("OpenSRS Error: Ensure port 55443 is open and PHP is compiled with OpenSSL."));
        }
        foreach ($return as $key=>$val) {
            if ($val['@']['key'] == 'response_code') $status_key = $key;
            if ($val['@']['key'] == 'is_success') $success_key = $key;
            if ($val['@']['key'] == 'response_text') $status_text = $key;
            if ($val['@']['key'] == 'attributes') $attributes_key = $key;
        }

        $this->logger->log(4, "OpenSRS Registration Response: ".$return[$status_text]['#']);

        if (isset($attributes_key)) {
            $attributes = $return[$attributes_key]['#']['dt_assoc'][0]['#']['item'];
            if ($return[$success_key]['#'] == 1) {
                foreach ($attributes as $key=>$val) {
                    if ($val['@']['key'] == 'id') $regId = $val['#'];
                }
            }
        }
        $code = $return[$status_key]['#'];
        if ($code == 210 || $code == 200 || $code == 250) return array($regId);
        if ($code == 485) return array(0);
        return array(-1, array("Domain registration failed: ".$return[$status_text]['#']));
    }


    /**
     * Function to change the auto renew status of a given domain.
     *
     * First gets a "cookie" from OpenSRS to edit the given domain
     *
     * @return array
     */
    function setAutorenew($params)
    {
        // Calculate the host
        $host = ($params['Use testing server'])? $this->testHost:$this->liveHost;

        // Start the connection
        $opensrs = new OpenSRS($host, $this->connPort, $params['Username'], $params['Private Key'], $this->logger);

        // Get the cookie
        $cookie = $opensrs->get_cookie($params);

        // Run the command
        $return = $opensrs->set_autorenew(strtolower($params['sld']), strtolower($params['tld']), $params['autorenew'], $cookie);

        // Check for an error
        if ($return['status']['response_code'] != 200) {
            $this->logger->log(4, "OpenSRS API Call Failed: ".$return['status']['response_text']);
            throw new Exception("OpenSRS API Error - setAutorenew: ".$return['status']['response_text']);
        }
    }

    /**
     * Function to get the general information of a given domain
     *
     * First gets a "cookie" from OpenSRS to edit the given domain
     *
     * @return array
     */
    function getGeneralInfo($params)
    {
        // Calculate the host
        $host = ($params['Use testing server'])? $this->testHost:$this->liveHost;

        // Start the connection
        $opensrs = new OpenSRS($host, $this->connPort, $params['Username'], $params['Private Key'], $this->logger);

        // Get the cookie
        $cookie = $opensrs->get_cookie($params);

        // Get the domain info
        $return = $opensrs->get_domain_info(strtolower($params['sld']), strtolower($params['tld']), $cookie);

        // Check for an error
        if ($return['status']['response_code'] != 200) {
            $this->logger->log(4, "OpenSRS API Call Failed: ".$return['status']['response_text']);
            throw new Exception("OpenSRS API Error - getGeneralInfo: ".$return['status']['response_text']);
        }

        // Build the standard CE response
        $data = array();
        $data['id'] = -1;
        $data['domain'] = strtolower($params['sld']).".".strtolower($params['tld']);
        $data['expiration'] = $return['generalInfo']['registry_expiredate'];
        $data['registrationstatus'] = 'Registered';
        $data['purchasestatus'] = 'Purcahsed on '.$return['generalInfo']['registry_createdate'];
        $data['autorenew'] = $return['generalInfo']['auto_renew'];

        return $data;
 
    }

    function disableRenewal($params)
    {
    }


    // @access private
    function _plugin_opensrs_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 = $this->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";
    }
}

?>
