Open sidebar
<?php class mgrUnexceptedResponse extends Exception { public $response; function __construct(SimpleXMLElement $response) { $this->message = 'Unexcepted XML-response received from server'; $this->response = $response; } } class mgrError extends Exception { public $code; public $obj; public $val; public $errorText; public $errorCodes = array( 1 => 'Internal error', 2 => 'Element already exists', 3 => 'Element not exists', 4 => 'Invalid value', 5 => 'Limit exceed', 6 => 'Access denied', 7 => 'Licence problem', 8 => 'Message error', 9 => 'Direct error', 10 => 'Addon error', 11 => 'Not enought money', 100 => 'Unknown error' ); public function __construct(SimpleXMLElement $error) { $this->code = intval(mgrAPI::getAttribute($error, 'code')); $this->errorText = trim(strval($error)); if ($this->code<1 || $this->code>999) throw new mgrUnexceptedResponse($error); $this->obj = mgrAPI::getAttribute($error, 'obj'); $this->val = mgrAPI::getAttribute($error, 'val'); $this->message = 'Error ' . $this->code; if (isset($this->errorCodes[$this->code])) $this->message .= ' (' . $this->errorCodes[$this->code] . ')'; if ($this->errorText!=='') $this->message .= ': ' . $this->errorText; } } class mgrAPI { const AUTH_ANONYMOUS = 1; const AUTH_SESSID = 2; const AUTH_AUTHINFO = 3; const AUTH_SHELL = 4; protected $authType = null; protected $sessid = null; protected $username = null; protected $password = null; protected $mgrURL = null; protected $mgrctlCommand = null; protected $lastResponse = null; public $curlOptions = null; public $stderrHandler = null; public $throwMgrErrors = true; /*************************** *** Конструкторы объекта *** ***************************/ public static function constructAnonymous($mgrURL) { $result = new mgrAPI; $result->initAnonymous($mgrURL); return $result; } public static function constructShell($mgrctlCommand) { $result = new mgrAPI; $result->initShell($mgrctlCommand); return $result; } public static function constructAuthinfo($mgrURL, $username, $password) { $result = new mgrAPI; $result->initAuthinfo($mgrURL, $username, $password); return $result; } public static function constructSessid($mgrURL, $sessid) { $result = new mgrAPI; $result->initSessid($mgrURL, $sessid); return $result; } public static function constructSessidLogin($mgrURL, $username, $password) { $result = new mgrAPI; $result->initSessidLogin($mgrURL, $username, $password); return $result; } protected function __construct() { } /************************************************ *** Инициализаторы инстанса для конструкторов *** ************************************************/ protected function initAnonymous($mgrURL) { $this->mgrURL = $mgrURL; $this->authType = $this::AUTH_ANONYMOUS; } protected function initShell($mgrctlCommand) { $this->mgrctlCommand = $mgrctlCommand; $this->authType = $this::AUTH_SHELL; } protected function initAuthinfo($mgrURL, $username, $password) { $this->mgrURL = $mgrURL; $this->username = $username; $this->password = $password; $this->authType = $this::AUTH_AUTHINFO; } protected function initSessid($mgrURL, $sessid) { $this->mgrURL = $mgrURL; $this->sessid = $sessid; $this->authType = $this::AUTH_SESSID; return $this->sessid; } protected function initSessidLogin($mgrURL, $username, $password) { $this->mgrURL = $mgrURL; $this->username = $username; $this->password = $password; $arguments = compact('username', 'password'); $response = $this->httpRequest('auth', $arguments); if (isset($response->authfail)) throw new Exception('Authentication failed'); $this->checkError($response); if (empty($response->auth)) throw new mgrUnexceptedResponse($response); $this->sessid = $this->getAttribute($response->auth, 'id'); if (is_null($this->sessid)) throw new mgrUnexceptedResponse($response); $this->authType = $this::AUTH_SESSID; return $this->sessid; } protected function initSessidKey($mgrURL, $username, $key) { $this->mgrURL = $mgrURL; $this->username = $username; $arguments = compact('key', 'username'); $response = $this->httpRequest('auth', $arguments); if (isset($response->authfail)) throw new Exception('Authentication failed'); $this->checkError($response); if (empty($response->auth)) throw new mgrUnexceptedResponse($response); $this->sessid = $this->getAttribute($response->auth, 'id'); if (is_null($this->sessid)) throw new mgrUnexceptedResponse($response); $this->authType = $this::AUTH_SESSID; return $this->sessid; } /*********************************** *** Рабочий код инстанса объекта *** ***********************************/ public function __get($property) { static $allowed = array( 'authType', 'sessid', 'username', 'password', 'mgrURL', 'mgrctlCommand', 'lastResponse' ); if (in_array($property, $allowed)) return $this->$property; throw new Exception(get_class($this) . ": attempt to read inaccessible property $property"); } public function newKey($username=null, $key=null) { if (is_null($key)) $key = $this->keygen(32); elseif (strlen($key)<16) throw new Exception('Length of key cannot be less than 16 characters'); $arguments = array('key'=>$key); if (!is_null($username)) $arguments['username'] = $username; $response = $this->query('session.newkey', $arguments); $this->checkError($response); if (isset($response->ok)) return $key; throw new mgrError($response->error); } public function query($function, $arguments=null) { switch ($this->authType): case $this::AUTH_ANONYMOUS: if (!is_array($arguments)) $arguments = array(); $result = $this->httpRequest($function, $arguments); return $result; case $this::AUTH_SESSID: if (!is_array($arguments)) $arguments = array(); $arguments['auth'] = $this->sessid; $result = $this->httpRequest($function, $arguments); return $result; case $this::AUTH_AUTHINFO: if (!is_array($arguments)) $arguments = array(); $arguments['authinfo'] = $this->username . ':' . $this->password; $result = $this->httpRequest($function, $arguments);; return $result; case $this::AUTH_SHELL: if (!is_array($arguments)) $arguments = array(); $arguments['out'] = 'xml'; $command = escapeshellcmd($this->mgrctlCommand); $command .= ' ' . escapeshellcmd($function); foreach ($arguments as $parameterName=>$parameterValue) { $command .= ' '; $command .= escapeshellarg($parameterName); $command .= '='; $command .= escapeshellarg($parameterValue); } $this->cmdOutput($command, $stdout, $stderr); if ($stderr!=='' && !is_null($this->stderrHandler)) { if (is_string($this->stderrHandler)) { if (!function_exists($this->stderrHandler)) throw new Exception("stderrHandler function '{$this->stderrHandler}' not exists"); } elseif (is_object($this->stderrHandler)) { $ok = ($x instanceof Closure); if (!$ok) throw new Exception('Unexcepted type of stderrHandler (1)'); } else { throw new Exception('Unexcepted type of stderrHandler (2)'); } $handlerArguments = array($this, $function, &$arguments, &$stdout, &$stderr); call_user_func_array($this->stderrHandler, $handlerArguments); } if ($stdout==='') { if ($stderr!=='') throw new Exception("Empty stdout received from mgrctl. Stderr: $stderr"); throw new Exception('Empty stdout received from mgrctl'); } $result = new SimpleXMLElement($stdout); return $result; default: throw new Exception('Unsupported authType: ' . $this->authType); endswitch; } function tryQuery() { $result = call_user_func_array(array($this, 'query'), func_get_args()); if (isset($result->error)) throw new mgrError($result->error); return $result; } public function skipInvalidSSL($skip) { if (!is_array($this->curlOptions)) $this->curlOptions = array(); if ($skip) { $this->curlOptions[CURLOPT_SSL_VERIFYHOST] = 0; $this->curlOptions[CURLOPT_SSL_VERIFYPEER] = 0; } else { $this->curlOptions[CURLOPT_SSL_VERIFYHOST] = 2; $this->curlOptions[CURLOPT_SSL_VERIFYPEER] = 1; } } protected function httpRequest($function, $arguments=null, &$requestInfo=null) { $this->lastResponse = null; if (!is_array($arguments)) $arguments = array(); $arguments['out'] = 'xml'; $arguments['func'] = $function; $response = $this->httpPost($this->mgrURL, $arguments, $this->curlOptions, $requestInfo); if (isset($requestInfo['content_type'])) if (!preg_match('/^text\/xml($| )/i', $requestInfo['content_type'])) throw new Exception('Server returns non-xml response'); if ($response==='') throw new Exception('HTTP-response with empty body received from server'); $result = new SimpleXMLElement($response); $this->lastResponse = $result; return $result; } protected static function httpGet($url, $curlOptions=null, &$requestInfo=null) { $ch = curl_init($url); if (!is_resource($ch)) throw new Exception('Failed to initialize cURL'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); if (is_array($curlOptions)) curl_setopt_array($ch, $curlOptions); $result = curl_exec($ch); $requestInfo = curl_getinfo($ch); $errno = curl_errno($ch); if ($errno!==0) throw new Exception("cURL error $errno: " . curl_error($ch)); curl_close($ch); return $result; } protected static function httpPost($url, $postData=null, $curlOptions=null, &$requestInfo=null) { $ch = curl_init($url); if (!is_resource($ch)) throw new Exception('Failed to initialize cURL'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); if (!is_null($postData)) curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); if (is_array($curlOptions)) curl_setopt_array($ch, $curlOptions); $result = curl_exec($ch); $requestInfo = curl_getinfo($ch); $errno = curl_errno($ch); if ($errno!==0) throw new Exception("cURL error $errno: " . curl_error($ch)); curl_close($ch); return $result; } protected static function keygen($length=32) { $result = ''; for ($j=0; $j<$length; $j++) switch(rand(0, 2)): case 0: $result .= chr(rand(97, 122)); break; case 1: $result .= chr(rand(65, 90)); break; case 2: $result .= chr(rand(48, 57)); break; endswitch; return $result; } public static function getAttribute(SimpleXMLElement $tag, $attributeName) { foreach ($tag->attributes() as $name=>$value) if ($name===$attributeName) return strval($value); return null; } public function checkError(SimpleXMLElement $lastResponse=null) { if (is_null($lastResponse)) $lastResponse = $this->lastResponse; if (isset($lastResponse->error)) throw new mgrError($lastResponse->error); } protected function cmdOutput($command, &$stdout, &$stderr) { $stdout = ''; $stderr = ''; $descriptorspec = array( 1 => array('pipe', 'w'), // stdout 2 => array('pipe', 'w') // stderr ); $proc = proc_open($command, $descriptorspec, $pipes); if (!is_resource($proc)) throw new Exception("Failed to create process by command: $command"); $stdout = stream_get_contents($pipes[1]); $stderr = stream_get_contents($pipes[2]); proc_close($proc); } } ?>
Close sidebar
Back
Please note that all pasted data is publicly available.
Twitter
GitHub
Use setting
Back
Please note that all pasted data is publicly available.
Twitter
GitHub
Use setting