From 100819dc9c6cd8c9637c1ef1f90cda72dce266b9 Mon Sep 17 00:00:00 2001 From: SecretR Date: Sat, 11 May 2013 19:45:59 +0300 Subject: [PATCH] Remote communication rewrite started, work in progress --- e107_handlers/e_marketplace.php | 458 ++++++++++++++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 e107_handlers/e_marketplace.php diff --git a/e107_handlers/e_marketplace.php b/e107_handlers/e_marketplace.php new file mode 100644 index 000000000..d521c6dad --- /dev/null +++ b/e107_handlers/e_marketplace.php @@ -0,0 +1,458 @@ +adapter = new $className(); + } + elseif(!class_exists('SoapClient')) $this->adapter = new e_marketplace_adapter_xmlrpc(); + else + { + $this->adapter = new e_marketplace_adapter_wsdl(); + } + } + + /** + * Set authorization key + */ + public function generateAuthKey($username, $password) + { + $this->setAuthKey($this->makeAuthKey($username, $password, true)); + return $this; + } + + /** + * Set authorization key + */ + public function setAuthKey($authkey) + { + $this->adapter->setAuthKey($authkey); + return $this; + } + + public function hasAuthKey() + { + return $this->adapter->hasAuthKey(); + } + + /** + * Make authorization key from user credentials + */ + public function makeAuthKey($username, $password = '', $plain = false) + { + $now = gmdate('y-m-d H'); + if($plain && !empty($password)) $password = md5($password); + return sha1($username.$password.$now); + } + + /** + * Retrieve currently used adapter + * @param e_marketplace_adapter_abstract + */ + public function adapter() + { + return $this->adapter; + } + + /** + * Retrieve currently used adapter + * @param e_marketplace_adapter_abstract + */ + public function call($method, $data, $apply = true) + { + return $this->adapter()->call($method, $data, $apply); + } + + /** + * Direct adapter()->call() execution - experimental stage + */ + public function __call($method, $arguments) + { + if(strpos($method, 'get') === 0 || strpos($method, 'do') === 0) + { + return $this->adapter()->call($method, $arguments); + } + throw new Exception("Error Processing Request", 10); + } + + + public function __destruct() + { + $this->adapter = null; + //echo "Adapter destroyed", PHP_EOL; + } + +} + +abstract class e_marketplace_adapter_abstract +{ + /** + * e107.org download URL + * @var string + */ + protected $downloadUrl = 'http://e107.org/e107_plugins/addons/request.php'; + + /** + * e107.org authorization key + * @var string + */ + protected $authKey = null; + + abstract public function test($input); + abstract public function call($method, $data, $apply); + abstract public function fetch($method, &$result); + + /** + * Set authorization key + */ + public function setAuthKey($authkey) + { + $this->authKey = $authkey; + return $this; + } + + + public function hasAuthKey() + { + return ($this->authKey !== null) ? true : false; + } + public function getAuthKey() + { + return $this->authKey; + } + + + /** + * Download a Plugin or Theme to Temp, then test and move to plugin/theme folder and backup to system backup folder. + * @param string $remotefile URL + * @param string $type plugin or theme + */ + public function download($id, $type='theme') + { + $tp = e107::getParser(); + $id = intval($id); + $qry = 'id='.$id; + $remotefile = $this->downloadUrl."?auth=".$this->getAuthKey()."&".$qry; + + $localfile = md5($remotefile.time()).".zip"; + $status = "Downloading..."; + + $result = $this->getRemoteFile($remotefile, $localfile); + + if(!file_exists(e_TEMP.$localfile)) + { + $status = ADMIN_FALSE_ICON."
Download Manually"; + + if(E107_DEBUG_LEVEL > 0) + { + $status .= 'local='.$localfile; + } + + echo $status; + exit; + } + else + { + $contents = file_get_contents(e_TEMP.$localfile); + if(strlen($contents) < 400) + { + echo ""; + return; + } + } + + chmod(e_TEMP.$localfile, 0755); + require_once(e_HANDLER."pclzip.lib.php"); + + $archive = new PclZip(e_TEMP.$localfile); + $unarc = ($fileList = $archive -> extract(PCLZIP_OPT_PATH, e_TEMP, PCLZIP_OPT_SET_CHMOD, 0755)); // Store in TEMP first. + $dir = $this->getRootFolder($unarc); + $destpath = ($type == 'theme') ? e_THEME : e_PLUGIN; + $typeDiz = ucfirst($type); + + @copy(e_TEMP.$localfile, e_BACKUP.$dir.".zip"); // Make a Backup in the system folder. + + if($dir && is_dir($destpath.$dir)) + { + $alert = $tp->toJS(ucfirst($type)." Already Installed".$destpath.$dir); + echo ""; + echo "Already Installed"; + @unlink(e_TEMP.$localfile); + exit; + } + + if($dir == '') + { + echo ""; + @unlink(e_TEMP.$localfile); + exit; + } + + if(is_dir(e_TEMP.$dir)) + { + $status = "Unzipping..."; + if(!rename(e_TEMP.$dir,$destpath.$dir)) + { + $alert = $tp->toJS("Couldn't Move ".e_TEMP.$dir." to ".$destpath.$dir." Folder"); + echo ""; + @unlink(e_TEMP.$localfile); + exit; + } + + $alert = $tp->toJS("Download Complete!"); + echo ""; + + // $dir = basename($unarc[0]['filename']); + // $plugPath = preg_replace("/[^a-z0-9-\._]/", "-", strtolower($dir)); + $status = "Done"; // ADMIN_TRUE_ICON; + + } + else + { + $status = ADMIN_FALSE_ICON."
Download Manually"; + if(E107_DEBUG_LEVEL > 0) + { + $status .= print_a($unarc, true); + } + } + + echo $status; + @unlink(e_TEMP.$localfile); + exit; + } + + // Grab a remote file and save it in the /temp directory. requires CURL + function getRemoteFile($remote_url, $local_file, $type='temp') + { + $path = ($type == 'media') ? e_MEDIA : e_TEMP; + + $fp = fopen($path.$local_file, 'w'); // media-directory is the root. + + $cp = curl_init($remote_url); + curl_setopt($cp, CURLOPT_FILE, $fp); + curl_setopt($cp, CURLOPT_REFERER, e_REQUEST_HTTP); + curl_setopt($cp, CURLOPT_HEADER, 0); + curl_setopt($cp, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); + curl_setopt($cp, CURLOPT_COOKIEFILE, e_SYSTEM.'cookies.txt'); + + $buffer = curl_exec($cp); + + curl_close($cp); + fclose($fp); + + return ($buffer) ? true : false; + } +} + +class e_marketplace_adapter_wsdl extends e_marketplace_adapter_abstract +{ + /** + * e107.org WSDL URL + * @var string + */ + protected $wsdl = 'http://e107.org/e107_plugins/addons/service.php?wsdl'; + + /** + * Soap client instance + * @var SoapClient + */ + protected $client = null; + + public function __construct() + { + e107_ini_set('soap.wsdl_cache_enabled', 0); + e107_ini_set('soap.wsdl_cache_ttl', 0); + + $options = array( + "trace" => true, + 'exception' => true, + "uri" => "http://server.soap.e107.inc.com/", + 'cache_wsdl' => WSDL_CACHE_NONE, + 'connection_timeout' => 10, + ); + + $this->client = new SoapClient($this->wsdl, $options); + + if(function_exists('xdebug_disable')) + { + //xdebug_disable(); + } + } + + public function test($input) + { + try + { + $res = $this->client->get_echo($input); + } + catch(Exception $e) + { + $res = $e->getMessage(); + } + return $res; + + } + + /** + * Generic call method + */ + public function _call($method, $args, $apply = true) + { + $result = array( + 'data' => null, + //'error'=> array('code' => 0, 'message' => null) + ); + $ret = null; + + // authorize on every call, service class decides what to do on every method call + $auth = new stdClass; + $auth->authKey = $this->getAuthKey(); + $header = new SoapHeader('http://e107.org/services/auth', 'checkAuthHeader', $auth); + + try + { + $this->client->__setSoapHeaders(array($header)); + if(is_array($args) && $apply) + { + $ret = call_user_func_array(array($this->client, $method), $args); + } + else $ret = $this->client->$method($args); + + if(isset($ret['exception'])) + { + $result['error']['message'] = "API Exception [call::{$method}]: (#".$ret['exception']['code'].") ".$ret['exception']['message']; + $result['error']['code'] = $ret['exception']['code']; + unset($ret['exception']); + } + $result['data'] = $ret['data']; + } + catch(SoapFault $e) + { + $result['error']['message'] = "SoapFault Exception [call::{$method}]: (#".$e->getCode().") ".$e->getMessage(); + $result['error']['code'] = 'SOAP_'.$e->getCode(); + } + catch(Exception $e) + { + $result['error']['message'] = "Generic Exception [call::{$method}]: (#".$e->getCode().") ".$e->getMessage(); + $result['error']['code'] = 'GEN_'.$e->getCode(); + } + if(E107_DEBUG_LEVEL) + { + print_a($this->client->__getLastRequest()); + } + return $result; + } + + /** + * Public call method + */ + public function call($method, $data, $apply = true) + { + return $this->_call($method, $data, $apply); + } + + /** + * Prepare the result, not needed for WSDL + * SUBJECT OF REMOVAL + */ + public function fetch($method, &$result) + { + if(isset($result['error'])) + { + return $result; + } + + switch ($method) + { + case 'getList': + break; + } + return $result; + } + + public function __destruct() + { + $this->client = null; + //echo "SOAP Client destroyed", PHP_EOL; + } +} + +class e_marketplace_adapter_xmlrpc extends e_marketplace_adapter_abstract +{ + /** + * e107.org XML-rpc service + * @var xmlClass + */ + protected $url = 'http://e107.org/e107_plugins/addons/xservice.php'; + + public function __construct() + { + } + + public function test($input) + { + + } + + public function call($method, $data, $apply = true) + { + $client = $this->client(); + + // settings based on current method + $this->prepareClient($client); + + // authorization data + $data['auth'] = $this->getAuthKey(); + $data['action'] = $method; + + // build the request query + $qry = str_replace(array('s%5B', '%5D'), array('[', ']'), http_build_query($data, null, '&')); + $url = $this->url.'?'.$qry; + + // call it + $result = $client->loadXMLfile($url,'advanced'); + //var_dump($url, $result); + return $result; + } + + public function fetch($method, &$result) + { + + } + + public function prepareClient($method, &$client) + { + switch ($method) + { + case 'getList': + $client->setOptArrayTags('plugin'); + break; + } + } + + public function client() + { + return e107::getXml(false); + } +}