Location: PHPKode > scripts > Enom API > enom-api/class.EnomInterface.php
<?php
//
// +-----------------------------------+
// |          Enom API v 1.0.2         |
// |      http://www.SysTurn.com       |
// +-----------------------------------+
//
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the ISLAMIC RULES and GNU Lesser General Public
//   License either version 2, or (at your option) any later version.
//
//   ISLAMIC RULES should be followed and respected if they differ
//   than terms of the GNU LESSER GENERAL PUBLIC LICENSE
//
//   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 license with this software;
//   If not, please contact support @ S y s T u r n .com to receive a copy.
//

/*
 CHANGES LOG:-
 ============
 - 17 August 2006 : Edited function _returnError() so the $error variable will not be constructed unless debugging is enabled.
 - 17 August 2006 : Added Inline documentation
*/


/**
 * EnomInterface class
 *
 * This class contains all the main functions that open connection
 * to Enom web servers, send command and queries and finlly parse
 * the response. It also contain the global error handler.
 *
 * @author   Bakr Alsharif <bakr AT systurn DOT com>
 * @website  http://systurn.com/
 * @version  1.0.2   17 August 2006
 */
Class EnomInterface
{
  /**
  * Connects to Enom's live server or test server
  */
  var $isLive;
  
  /**
  * Use SSL while connectins or HTTP connections
  */
  var $useSSL;
  
  /**
  * Enom account username
  */
  var $user;
  
  /**
  * Enom account password
  */
  var $pass;
  
  
  /**
  * Command parameters Array
  */
  var $params = array();
  
  /**
  * String containing the request being sent to enom's server
  */
  var $rawRequest = '';
  
  /**
  * String containing the response returned from enom's server, including response Headers
  */
  var $rawResponse = '';
  
  /**
  * Array holds the parsed response as key=>value
  */
  var $response = array();
  
  /**
  * Error flag. If an error occured while prepairing for request, or if enom's server
  * returned an error, this variable will be true. Otherwise if succeeded
  * it will be false.
  */
  var $isError = false;
  
  /**
  * Debugging flag, if set to true, error messages will be printed on screen
  */
  var $debug = false;
  
  /**
  * A flag, if set to true, the script will exit if any error occured
  */
  var $dieOnError = false;
  
  
  
  /**
  * CONSTRUCTOR Function
  *
  * Valid Enom account username and password must be used.
  *
  * @param      string      $user
  * @param      string      $pass
  * @param      bool        $use_ssl        if true, SSL connections will be used (Requires libcurl). default iif not passed is true
  * @param      bool        $is_live        if true, Connections will be made to Enom's live server. Otherwise, it will be made to Enom's test server. default if not passed is false
  * @see        _sslProcess
  */
  function EnomInterface($user, $pass, $use_ssl = true, $is_live = false)
  {
    $this->user = $user;
    $this->pass = $pass;
    $this->useSSL = $use_ssl;
    $this->isLive = $is_live;
  }
  
  
  /**
  * Add new or edit a previousely added command parameter
  *
  * the value will be urlencoded before it's being stored in $this->params array
  *
  * @return     void
  * @param      string      $name       Parameter name
  * @param      string      $value      Parameter value    
  * @access     public
  * @see        _setCommand
  */
  function addParam($name, $value)
  {
    $this->params[$name] = urlencode($value);
  }
  
  
  /**
  * Process the request to enom's servers
  *
  * This function will built the command request string then it connects to enom's live or test server
  * to execute the command, get the response and parse it, to finally store the parsed response as key=>value
  * pairs in $this->response array. If SSL connection is enabled, _sslProcess() will be called.
  *
  * @return     bool        returns true on success, false if any error occured
  * @access     public
  * @see        _sslProcess
  */
  function process()
  {
    if( empty($this->user) || empty($this->pass) )
    {
      $this->_addError('You must specify Username and Password.');
      return $this->_returnError();
    }
    if( !count($this->params) )
    {
      $this->_addError('You must set request params first before calling process().');
      return $this->_returnError();
    }

    $this->rawRequest = 'UID=' . $this->user . '&PW=' . $this->pass . '&ResponseType=Text';
    
    foreach($this->params as $key=>$val)
    {
      $this->rawRequest .= "&$key=$val";
    }
    
    if($this->isLive)
    {
      $host = 'reseller.enom.com';
    }
    else
    {
      $host = 'resellertest.enom.com';
    }
    
    if($this->useSSL)
    {
      return $this->_sslProcess('https://' . $host . '/interface.asp?' . $this->rawRequest);
    }
    
    $this->rawRequest = 'GET /interface.asp?' . $this->rawRequest . " HTTP/1.0\r\n\r\n";
    
    $socket = @fsockopen($host, 80, $errno, $errstr);
    
    if(!$socket)
    {
      $this->_addError("Could not connect to Server - Error($errno) $errstr");
      return $this->_returnError();
    }
    
    fputs($socket, $this->rawRequest);
    
    $in_head = true;
    $got_values = false;
    while( ($line = fgets($socket, 2048)) )
    {
      $this->rawResponse .= $line;

      if( $in_head && ("\n" == $line || "\r\n" == $line) )
      {
        $in_head = false;
        continue;
      }
      
      if( !$in_head )
      {
        if( '' == trim($line) || ';' == substr($line, 0, 1) ) continue;
        list($key, $val) = explode('=', $line);
        $this->response[ trim($key) ] = trim($val);

        if( 'Done' == trim($key) ) $got_values = true;
      }
    }
    fclose($socket);
    
    if( !$got_values )
    {
      $this->_addError('Could not find any return values from the server');
      return $this->_returnError();
    }
    
    return true;
  }
  
  /**
  * Process a HTTPS request to enom's servers
  * 
  * This function requires libcurl
  * 
  * @return     bool                    returns true on success, false if any error occured
  * @param      string      $url        The url which should be built in process() function
  * @access     private
  * @see        process
  * @see        _curlHeaders
  */
  function _sslProcess($url)
  {
    if( !function_exists('curl_init') )
    {
      $this->_addError('Could not connect to Server though SSL - libcurl is not supported');
      return $this->_returnError();
    }

    $version = curl_version();
    $supports_insecure = false;
    #insecure key is supported by curl since version 7.10
    if( preg_match('/libcurl\/([^ $]+)/', $version, $m) )
    {
        $parts = explode('.', $m[1]);
        if( $parts[0] > 7 || ($parts[0] = 7 && $parts[1] >= 10) )
        {
          $supports_insecure = true;
        }
    }

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    if ($supports_insecure)
    {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, '_curlHeaders'));
    $this->_curlHeaders(false);

    $body = curl_exec($ch);
    $errno = curl_errno($ch);
    $errstr = curl_error($ch);
    curl_close ($ch);
    if( $errstr )
    {
      $this->_addError("Could not connect to Server - Error($errno) $errstr");
      return $this->_returnError();
    }
    $this->rawResponse = $this->_curlHeaders(true) . "\r\n" . $body;
    $lines = explode("\n", $body);

    $got_values = false;
    foreach($lines as $line)
    {
      if( '' == trim($line) || ';' == substr($line, 0, 1) ) continue;
      list($key, $val) = explode('=', $line);
      $this->response[ trim($key) ] = trim($val);

      if( 'Done' == trim($key) ) $got_values = true;
    }

    if( !$got_values )
    {
      $this->_addError('Could not find any return values from the server');
      return $this->_returnError();
    }

    return true;
  }

  /**
  * Collects response headers from libcurl
  * 
  * @return     string          return a string containing the collected headers
  * @access     private
  * @see        _sslProcess
  */
  function _curlHeaders()
  {
    static $headers = '';

    $args = func_get_args();
    if (count($args) == 1)
    {
      $return = '';
      if($args[0] == true) $return = $headers;
      $headers = '';
      return $return;
    }

    if (trim($args[1]) != '') $headers .= $args[1];
    return strlen($args[1]);
  }
  
  
  /**
  * Adds a custom error to $this->response array
  * 
  * This function can be used to add a custom error to $this->response array.
  * For example if a non valid domain name is detected, you can add your custom error, and do not process the request
  * 
  * @return     void
  * @param      string      $error        The error message
  * @access     private
  */
  function _addError($error)
  {
    $this->response['ErrCount'] = '1';
    $this->response['Err1'] = $error;
  }
  
  
  /**
  * Returns false whnen an error occures
  * 
  * If any error occured, we do return $this->_returnError() instead of returning false.
  * This function will trigger a warnning. If debugging is enabled a detaild error message will be pronted on screen.
  * If die on error is enabled, the script will exit and stop execution.
  * 
  * @return     bool        always return false
  * @access     private
  */
  function _returnError()
  {
    $this->isError = true;

    trigger_error("Failed while executing command: <i>{$this->params['Command']}</i>", E_USER_WARNING);

    if($this->debug)
    {
        $error = '';
        $error .= "<pre>Failed while executing command: <i>{$this->params['Command']}</i>\r\n\r\n<b><u>Params Sent</u></b>\r\n";
        $error .= print_r($this->params, true);
        $error .= "\r\n<b><u>Found Errors:</u></b>\r\n";
        $error .= '<ul>';
        for($i=1; $i<=$this->response['ErrCount']; $i++)
        {
            $error .= '<li>' . $this->response[ ('Err' . $i) ] . '</li>';
        }
        $error .= '</ul>';
        $error .= "\r\n<b><u>Request sent to server:</u></b>\r\n{$this->rawRequest}\r\n";
        $error .= "\r\n<b><u>Server Reply:</u></b>\r\n";
        $error .= htmlentities($this->rawResponse);
        $error .= '</pre>';
        
        echo $error;
    }

    if($this->dieOnError) exit;

    return false;
  }
  
  
  /**
  * Initialize new command request to enom's servers
  * 
  * This function will prepair for new request, and set the Command parameter.
  * Should be called only inside the EnomService class functions, to initialize new command execution.
  * 
  * @return     void
  * @param      string      $command        The command to be executed
  * @access     private
  * @see        addParam
  */
  function _setCommand($command)
  {
    $this->params = array();
    $this->rawRequest = '';
    $this->rawResponse = '';
    $this->response = array();
    $this->isError = false;
    $this->addParam('Command', $command);
  }
  
  
  /**
  * Check if the passed SLD (Second-level domain) is valid or not
  * 
  * Enom says in it's API documentations, that valid SLD must meet the following requirements:
  * 
  *     - Must be composed of the letters a through z, the numbers 0 through 9, and the hyphen (-) character.
  *     - Some foreign character sets can display onscreen, but resolve to alphanumeric plus hyphen characters in the underlying code.
  *     - must not begin or end with the hyphen character.
  *     - must not contain spaces.
  *     - must not contain special characters other than the hyphen character.
  *     - The third and fourth characters must not both be hyphens unless it is an encoded international-character domain name.
  *     - must contain 2 to 63 characters, inclusive.
  * 
  * @param      string      $sld
  * @return     bool                    Return true if valid, Otherwise it return false 
  * @access     private
  * @see        _setParseDomain
  */
  function _isValidSLD($sld)
  {
    if( preg_match('/^[a-z0-9]+[a-z0-9\-]*[a-z0-9]+$/i', $sld) && strlen($sld) < 64 && substr($sld, 2, 2) != '--' )
    {
      return true;
    }
    else
    {
      return false;
    }
  }

  
  /**
  * Parse the passed domain name and set the SLD and TLD parameters
  * 
  * This function will check first if the passed domain name is valid or not, and returns false if not valid,
  * Otherwise it will set the TLD and SLD parameters to the parsed matches.
  * 
  * @param      string      $domainName
  * @return     bool                    Return true if valid, Otherwise it return false 
  * @access     private
  * @see        _isValidSLD
  * @see        addParam
  */
  function _setParseDomain($domainName)
  {
    if ( !preg_match('/^([a-z0-9]+[a-z0-9\-]*[a-z0-9]+)\.([a-z]+[a-z\.]*[a-z]+)$/i', $domainName, $parts) || !$this->_isValidSLD($parts[1]) )
    {
      return false;
    }
    $this->addParam('SLD', $parts[1]);
    $this->addParam('TLD', $parts[2]);
    return true;
  }
}
?>
Return current item: Enom API