mirror of
				https://github.com/e107inc/e107.git
				synced 2025-10-24 19:26:21 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			1392 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1392 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /*
 | |
|  * e107 website system
 | |
|  *
 | |
|  * Copyright (C) 2008-2013 e107 Inc (e107.org)
 | |
|  * Released under the terms and conditions of the
 | |
|  * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
 | |
|  *
 | |
|  * Application store client
 | |
|  *
 | |
|  */
 | |
| 
 | |
| e107::coreLan('theme', true);
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  */
 | |
| class e_marketplace
 | |
| {
 | |
| 	/**
 | |
| 	 * Protocol type, defaults to WSDL, fallback to 'xmlrpc' if soap extension not installed
 | |
| 	 * @var e_marketplace_adapter_abstract
 | |
| 	 */
 | |
| 	protected $adapter = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Adapter identifier
 | |
| 	 * @var string wsdl|xmlrpc
 | |
| 	 */
 | |
| 	protected $_adapter_name = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * Constructor
 | |
| 	 * @param string $force force adapter wsdl|xmlrpc, omit to switch to auto-detection
 | |
| 	 */
 | |
| 	public function __construct($force = null)
 | |
| 	{
 | |
| 		if(null !== $force)
 | |
| 		{
 | |
| 			$this->_adapter_name = $force === 'wsdl' ? 'wsdl' : 'xmlrpc';
 | |
| 		}
 | |
| 		elseif(!class_exists('SoapClient')) $this->_adapter_name = 'xmlrpc';
 | |
| 		else
 | |
| 		{
 | |
| 			$this->_adapter_name = 'wsdl';
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Set authorization key
 | |
| 	 * @deprecated subject of removal
 | |
| 	 */
 | |
| 	public function generateAuthKey($username, $password)
 | |
| 	{
 | |
| 		if(trim($username) == '' || trim($password) == '')
 | |
| 		{
 | |
| 			return false;	
 | |
| 		}
 | |
| 		$this->setAuthKey($this->makeAuthKey($username, $password, true));	
 | |
| 		return $this;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Set authorization key
 | |
| 	 * @deprecated subject of removal
 | |
| 	 */
 | |
| 	public function setAuthKey($authkey)
 | |
| 	{
 | |
| 		$this->adapter->setAuthKey($authkey);	
 | |
| 		return $this;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	public function hasAuthKey()
 | |
| 	{
 | |
| 		return $this->adapter->hasAuthKey();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Make authorization key from user credentials
 | |
| 	 * @deprecated subject of removal
 | |
| 	 */
 | |
| 	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);
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * Have the admin enter their e107.org login details in order to create the authorization key. 
 | |
| 	 * @deprecated subject of removal
 | |
| 	 */	
 | |
| 	public function renderLoginForm()
 | |
| 	{
 | |
| 		
 | |
| 	$text =	'
 | |
|           <div class="" id="loginModal">
 | |
| 		    <div class="well">
 | |
| 		    <img src="'.e_IMAGE_ABS.'admin_images/credits_logo.png" alt="" style="margin-bottom:15px" />
 | |
| 		    <ul class="nav nav-tabs">
 | |
| 			    <li class="active"><a href="#login" data-toggle="tab" data-bs-toggle="tab">Login</a></li>
 | |
| 			    <li><a href="#create" data-toggle="tab" data-bs-toggle="tab">Create Account</a></li>
 | |
| 		    </ul>
 | |
| 		    <div id="myTabContent" class="tab-content">
 | |
| 		    <div class="tab-pane active in" id="login">
 | |
| 		    <form class="form-horizontal" action="" method="POST">
 | |
| 			    <fieldset>
 | |
| 				    <div id="legend">
 | |
| 				    	<legend class="">Login</legend>
 | |
| 				    </div>
 | |
| 				    
 | |
| 					<div class="control-group">
 | |
| 					    <label class="control-label" for="username">Username</label>
 | |
| 						<div class="controls">
 | |
| 						   	<input type="text" id="username" name="username" placeholder="" class="input-xlarge">
 | |
| 						</div>
 | |
| 					</div>
 | |
| 					
 | |
| 				    <div class="control-group">
 | |
| 					    <label class="control-label" for="password">Password</label>
 | |
| 					    <div class="controls">
 | |
| 					    	<input type="password" id="password" name="password" placeholder="" class="input-xlarge">
 | |
| 					    </div>
 | |
| 				    </div>
 | |
| 				    
 | |
| 				    <div class="control-group">
 | |
| 					    <div class="controls">
 | |
| 					    	<button class="btn btn-success">Login</button>
 | |
| 					    </div>
 | |
| 				    </div>
 | |
| 				    
 | |
| 			    </fieldset>
 | |
| 		    </form>
 | |
| 		    </div>';
 | |
| 	
 | |
| 	//TODO Use Form handler for INPUT tags. 
 | |
| 	//XXX TBD OR do we just redirect to the signup page on the website, in an iframe? 
 | |
| 			
 | |
| 	$text .=	'
 | |
| 		    <div class="tab-pane fade" id="create">
 | |
| 		    <form class="form-horizontal" id="tab">
 | |
| 		     <div class="control-group">
 | |
| 		    	<label class="control-label">Username</label>
 | |
| 		     	<div class="controls">
 | |
| 		    		<input type="text" value="" class="input-xlarge">
 | |
| 		    	</div>
 | |
| 		    </div>
 | |
| 		     <div class="control-group">
 | |
| 		    	<label class="control-label">Password</label>
 | |
| 		    	 <div class="controls">
 | |
| 		   		 <input type="password" value="" class="input-xlarge">
 | |
| 		    	</div>
 | |
| 		    </div>
 | |
| 		     <div class="control-group">
 | |
| 		    	<label class="control-label">Email</label>
 | |
| 		    	 <div class="controls">
 | |
| 		    	<input type="text" value="" class="input-xlarge">
 | |
| 		    	</div>
 | |
| 		    </div>
 | |
| 		    <div class="control-group">
 | |
| 			    <div class="controls">
 | |
| 			   	 <button class="btn btn-primary">Create Account</button>
 | |
| 			    </div>
 | |
| 		    </div>
 | |
| 		    </form>
 | |
| 		    </div>
 | |
| 		    </div>
 | |
| 		    </div>
 | |
| 		  ';	
 | |
| 		
 | |
| 		return $text;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve currently used adapter
 | |
| 	 * @param e_marketplace_adapter_abstract
 | |
| 	 * @return \e_marketplace_adapter_abstract
 | |
| 	 */
 | |
| 	public function adapter()
 | |
| 	{
 | |
| 		if(null === $this->adapter)
 | |
| 		{
 | |
| 			$className = 'e_marketplace_adapter_'.$this->_adapter_name; 
 | |
| 			$this->adapter = new $className();
 | |
| 		}
 | |
| 		return $this->adapter;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Retrieve currently used adapter
 | |
| 	 * @param $method
 | |
| 	 * @param $data
 | |
| 	 * @param bool $apply
 | |
| 	 * @return mixed
 | |
| 	 */
 | |
| 	public function call($method, $data, $apply = true)
 | |
| 	{
 | |
| 		if(E107_DEBUG_LEVEL > 0)
 | |
| 		{
 | |
| 			e107::getDebug()->log("Calling e107.org  using <b> ".$this->_adapter_name."</b> adapter");
 | |
| 		}
 | |
| 		return $this->adapter()->call($method, $data, $apply);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Adapter proxy
 | |
| 	 */
 | |
| 	public function download($id, $mode, $type)
 | |
| 	{
 | |
| 		return $this->adapter()->download($id, $mode, $type);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * 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;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $data - e107.org plugin/theme feed data.
 | |
| 	 * @return bool|string
 | |
| 	 */
 | |
| 	public function getDownloadModal($type='plugin',$data=array())
 | |
| 	{
 | |
| 
 | |
| 		$url = false;
 | |
| 
 | |
| 		if($type === 'plugin')
 | |
| 		{
 | |
| 
 | |
| 			if(empty($data['plugin_id']))
 | |
| 			{
 | |
| 
 | |
| 				$srcData = array(
 | |
| 					'plugin_id'     => $data['params']['id'],
 | |
| 					'plugin_folder' => $data['folder'],
 | |
| 					'plugin_price'  => $data['price'],
 | |
| 					'plugin_mode'   => $data['params']['mode'],
 | |
| 					'plugin_url'    => $data['url'],
 | |
| 				);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				$srcData = $data;
 | |
| 			}
 | |
| 
 | |
| 			$d = http_build_query($srcData,false,'&');
 | |
| 
 | |
| 		//	if(deftrue('e_DEBUG_PLUGMANAGER'))
 | |
| 			{
 | |
| 				$url = e_ADMIN.'plugin.php?mode=online&action=download&e-token='.e_TOKEN.'&src='.base64_encode($d);
 | |
| 			}
 | |
| 		//	else
 | |
| 			{
 | |
| 			//	$url = e_ADMIN.'plugin.php?mode=download&src='.base64_encode($d);
 | |
| 			}
 | |
| 
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		if($type === 'theme')
 | |
| 		{
 | |
| 			$srcData = array(
 | |
| 				'id'    => $data['params']['id'],
 | |
| 				'url'   => $data['url'],
 | |
| 				'mode'  => 'addon',
 | |
| 				'price' => $data['price']
 | |
| 			);
 | |
| 
 | |
| 			$d = http_build_query($srcData,false,'&');
 | |
| 			$url = e_ADMIN.'theme.php?mode=main&action=download&e-token='.e_TOKEN.'&src='.base64_encode($d);//$url.'&action=download';
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		return $url;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $type
 | |
| 	 * @return array|string[]
 | |
| 	 */
 | |
| 	public function getVersionList($type='plugin')
 | |
| 	{
 | |
| 		$cache = e107::getCache();
 | |
| 		$cache->setMD5('_', false);
 | |
| 
 | |
| 		$tag = 'Versions_'.$type;
 | |
| 
 | |
| 		if($data = $cache->retrieve($tag,(60 * 12), true, true))
 | |
| 		{
 | |
| 			return e107::unserialize($data);
 | |
| 		}
 | |
| 
 | |
| 	//	$mp = $this->getMarketplace();
 | |
| 	//	$mp->generateAuthKey($e107SiteUsername, $e107SiteUserpass);
 | |
| 		e107::getDebug()->log("Retrieving ".$type." version list from e107.org");
 | |
| 
 | |
| 		$xdata = $this->call('getList', array(
 | |
| 			'type' => $type,
 | |
| 			'params' => array('limit' => 200, 'search' => null, 'from' => 0)
 | |
| 		));
 | |
| 
 | |
| 		$arr = array();
 | |
| 
 | |
| 		if(!empty($xdata['data']))
 | |
| 		{
 | |
| 
 | |
| 			foreach($xdata['data'] as $row)
 | |
| 			{
 | |
| 				$k = $row['folder'];
 | |
| 				$arr[$k] = $row;
 | |
| 			}
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		if(empty($arr))
 | |
| 		{
 | |
| 			$arr = array('-unable-to-connect'); // make sure something is cached so further lookups stop.
 | |
| 		}
 | |
| 
 | |
| 		$data = e107::serialize($arr, 'json');
 | |
| 		$cache->set($tag, $data, true, true, true);
 | |
| 
 | |
| 		return $arr;
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  */
 | |
| abstract class e_marketplace_adapter_abstract
 | |
| {
 | |
| 	/**
 | |
| 	 * e107.org download URL
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $downloadUrl = 'https://e107.org/request/';
 | |
| 	
 | |
| 	/**
 | |
| 	 * e107.org service URL [adapter implementation required]
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $serviceUrl = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Request method POST || GET  [adapter implementation required]
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $requestMethod = null;
 | |
| 	
 | |
| 
 | |
| 	/**
 | |
| 	 * @var eAuth
 | |
| 	 */
 | |
| 	protected $_auth = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * e107.org authorization key
 | |
| 	 * @deprecated subject of removal
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $authKey = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $input
 | |
| 	 * @return mixed
 | |
| 	 */
 | |
| 	abstract public function test($input);
 | |
| 	//abstract public function call($method, $data, $apply);
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $method
 | |
| 	 * @param $data
 | |
| 	 * @param $apply
 | |
| 	 * @return mixed
 | |
| 	 */
 | |
| 	abstract public function call($method, $data, $apply = true); // Fix issue #490
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $method
 | |
| 	 * @param $result
 | |
| 	 * @return mixed
 | |
| 	 */
 | |
| 	abstract public function fetch($method, &$result);
 | |
| 	
 | |
| 	/**
 | |
| 	 * Authorization object
 | |
| 	 * @return eAuth
 | |
| 	 */
 | |
| 	public function auth()
 | |
| 	{
 | |
| 		if(null === $this->_auth)
 | |
| 		{
 | |
| 			$this->_auth = new eAuth;
 | |
| 			$this->_auth->loadSysCredentials();
 | |
| 			$this->_auth->requestMethod = $this->requestMethod;
 | |
| 		}
 | |
| 		return $this->_auth;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Set authorization key
 | |
| 	 * @deprecated subject of removal
 | |
| 	 */
 | |
| 	public function setAuthKey($authkey)
 | |
| 	{
 | |
| 		$this->authKey = $authkey;
 | |
| 		return $this;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @deprecated subject of removal
 | |
| 	 */
 | |
| 	public function hasAuthKey()
 | |
| 	{
 | |
| 		return $this->authKey !== null;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @deprecated subject of removal
 | |
| 	 */
 | |
| 	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.
 | |
| 	 * XXX better way to return status (e.g. getError(), getStatus() service call before download)
 | |
| 	 * XXX temp is not well cleaned
 | |
| 	 * XXX themes/plugins not well tested after unzip (example - Headline 1.0, non-default structure, same applies to most FS net free themes)
 | |
| 	 * This method is direct outputting the status. If not needed - use buffer
 | |
| 	 * @param $id
 | |
| 	 * @param $mode
 | |
| 	 * @param string $type plugin or theme
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	public function download($id, $mode, $type)
 | |
| 	{
 | |
| 		$tp = e107::getParser();
 | |
| 		$mes = e107::getMessage();
 | |
| 		$fl = e107::getFile();
 | |
| 		
 | |
| 		$id = intval($id);
 | |
| 		$qry = 'id='.$id.'&type='.$type.'&mode='.$mode;
 | |
| 		$remotefile = $this->downloadUrl."?auth=".$this->getAuthKey()."&".$qry;
 | |
| 
 | |
| 		$localfile = md5($remotefile.time()).".zip";
 | |
| 		$mes->addSuccess(LAN_DOWNLOADING."...");
 | |
| 	
 | |
| 		// FIXME call the service, check status first, then download (if status OK), else retireve the error break and show it
 | |
| 		
 | |
| 		$result 	= $this->getRemoteFile($remotefile, $localfile);
 | |
| 		
 | |
| 		if(!$result)
 | |
| 		{
 | |
| 			if(filesize(e_TEMP.$localfile))
 | |
| 			{
 | |
| 				$contents = file_get_contents(e_TEMP.$localfile);
 | |
| 				$contents = explode('REQ_', $contents);
 | |
| 				$mes->addError('[#'.trim($contents[1]).'] '.trim($contents[0])); flush(); 
 | |
| 			}
 | |
| 			
 | |
| 			@unlink(e_TEMP.$localfile);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		
 | |
| 		if(!file_exists(e_TEMP.$localfile))
 | |
| 		{
 | |
| 			$srch = array("[", "]");
 | |
| 			$repl = array("<a href='".$remotefile."'>", "</a>");
 | |
| 
 | |
| 			$mes->addError( TPVLAN_83." ".str_replace($srch, $repl, TPVLAN_84));
 | |
| 			
 | |
| 			if(E107_DEBUG_LEVEL > 0)
 | |
| 			{
 | |
| 				$mes->addDebug('local='.$localfile); // ; flush(); 
 | |
| 			}
 | |
| 
 | |
| 			return false;
 | |
| 		}
 | |
| 		
 | |
| 		
 | |
| 		if($fl->unzipArchive($localfile,$type, true))
 | |
| 		{
 | |
| 			$lan = defset('LAN_DOWNLOAD_COMPLETE', 'Download Complete!');
 | |
| 			$mes->addSuccess($lan);
 | |
| 			return true; 
 | |
| 		}
 | |
| 		else 
 | |
| 		{
 | |
| 			$mes->addSuccess( "<a href='".$remotefile."'>".TPVLAN_84."</a>");
 | |
| 		}
 | |
| 		
 | |
| 		return false; 
 | |
| 	}
 | |
| 			
 | |
| 		
 | |
| 
 | |
| 	// Grab a remote file and save it in the /temp directory. requires CURL
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $remote_url
 | |
| 	 * @param $local_file
 | |
| 	 * @param $type
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	function getRemoteFile($remote_url, $local_file, $type='temp')
 | |
| 	{
 | |
| 		// FIXME - different methods (see xml handler getRemoteFile()), error handling, appropriate error messages, 
 | |
| 		if (!function_exists("curl_init")) 
 | |
| 		{
 | |
| 			return false;
 | |
| 		}
 | |
| 		$path = ($type == 'media') ? e_MEDIA : e_TEMP; 
 | |
| 		
 | |
|         $fp = fopen($path.$local_file, 'w'); // media-directory is the root. 
 | |
|         //$fp1 = fopen(e_TEMP.'/curllog.txt', 'w'); 
 | |
| 
 | |
| 
 | |
|         $cp = e107::getFile()->initCurl($remote_url);
 | |
|         curl_setopt($cp, CURLOPT_FILE, $fp);
 | |
|      /*   $cp = curl_init($remote_url);
 | |
| 
 | |
| 		
 | |
| 		//curl_setopt($ch, CURLOPT_VERBOSE, 1);
 | |
| 		//curl_setopt($ch, CURLOPT_STDERR, $fp1);
 | |
| 		
 | |
| 		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);
 | |
| 		//fclose($fp1);
 | |
| 		
 | |
| 		if($buffer)
 | |
| 		{
 | |
| 			$size = filesize($path.$local_file);
 | |
| 			if($size < 400) $buffer = false;
 | |
| 		}
 | |
| 		
 | |
|         return ($buffer) ? true : false;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  */
 | |
| class e_marketplace_adapter_wsdl extends e_marketplace_adapter_abstract
 | |
| {
 | |
| 	/**
 | |
| 	 * e107.org WSDL URL
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $serviceUrl = 'https://e107.org/service?wsdl';
 | |
| 	
 | |
| 	/**
 | |
| 	 * Request method POST || GET
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $requestMethod = 'POST';	
 | |
| 	
 | |
| 	/**
 | |
| 	 * Soap client instance
 | |
| 	 * @var SoapClient
 | |
| 	 */
 | |
| 	 protected $client = null;
 | |
| 	
 | |
| 	public function __construct()
 | |
| 	{
 | |
| 		ini_set('soap.wsdl_cache_enabled', 0);
 | |
| 		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' 	=> 5,
 | |
| 		);
 | |
| 
 | |
| 
 | |
| 		try
 | |
| 		{
 | |
| 			//libxml_disable_entity_loader(false);
 | |
|             $this->client = new SoapClient($this->serviceUrl, $options);
 | |
|         }
 | |
|         catch (Exception $e)
 | |
|         {
 | |
| 	        $message = deftrue('LAN_ERROR_CONNECTION', "Unable to connect for updates. Please check firewall and/or internet connection.");
 | |
|             e107::getMessage()->addInfo($message);
 | |
|             e107::getMessage()->addDebug($e->getMessage());
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
| 		if(function_exists('xdebug_disable'))
 | |
| 		{
 | |
| 			xdebug_disable();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $input
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	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('https://e107.org/services/auth', 'checkAuthHeader', $auth);
 | |
| 
 | |
| 		if(!is_object($this->client))
 | |
| 		{
 | |
| 			$result['exception'] = array();
 | |
| 			$result['exception']['message'] = "Unable to connect at this time.";
 | |
| 			return $result;
 | |
| 		}
 | |
| 		
 | |
| 		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);
 | |
| 			
 | |
| 			$result = $ret;
 | |
| 			if(isset($ret['exception']))
 | |
| 			{
 | |
| 				$result['exception'] = array();
 | |
| 				$result['exception']['message'] = "API Exception [call::{$method}]: (#".$ret['exception']['code'].") ".$ret['exception']['message'];
 | |
| 				$result['exception']['code'] 	= 'API_'.$ret['exception']['code'];
 | |
| 			}
 | |
| 			unset($ret);
 | |
| 		}
 | |
| 		catch(SoapFault $e)
 | |
| 		{
 | |
| 			$result['exception']['message'] = "SoapFault Exception [call::{$method}]: (#".$e->faultcode.") ".$e->faultstring;
 | |
| 			$result['exception']['code'] 	= 'SOAP_'.$e->faultcode;
 | |
| 			if(E107_DEBUG_LEVEL)
 | |
| 			{
 | |
| 				$result['exception']['trace'] = $e->getTraceAsString(); 
 | |
| 				$result['exception']['message'] .= ". Header fault: ".($e->headerfault ? $e->headerfault : 'n/a');
 | |
| 			}
 | |
| 		}
 | |
| 		catch(Exception $e)
 | |
| 		{
 | |
| 			$result['exception']['message'] = "Generic Exception [call::{$method}]: (#".$e->getCode().") ".$e->getMessage();
 | |
| 			$result['exception']['code'] 	= 'GEN_'.$e->getCode();
 | |
| 			if(E107_DEBUG_LEVEL)
 | |
| 			{
 | |
| 				$result['debug']['trace'] = $e->getTraceAsString(); 
 | |
| 			}
 | |
| 		}
 | |
| 		if(E107_DEBUG_LEVEL)
 | |
| 		{
 | |
| 			$result['debug']['response'] = $this->client->__getLastResponse(); 
 | |
| 			$result['debug']['request'] = $this->client->__getLastRequest(); 
 | |
| 			$result['debug']['request_header'] = $this->client->__getLastRequestHeaders(); 
 | |
| 		}
 | |
| 		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 $serviceUrl = 'https://e107.org/xservice';
 | |
| 	
 | |
| 	/**
 | |
| 	 * Request method POST || GET
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $requestMethod = 'GET';
 | |
| 	
 | |
| 	protected $_forceArray = array();
 | |
| 	protected $_forceNumericalArray = array();
 | |
| 	
 | |
| 	public function __construct()
 | |
| 	{
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $input
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public function test($input)
 | |
| 	{
 | |
| 		
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $method
 | |
| 	 * @param $data
 | |
| 	 * @param $apply
 | |
| 	 * @return array|string
 | |
| 	 */
 | |
| 	public function call($method, $data, $apply = true)
 | |
| 	{
 | |
| 		$client = $this->client();
 | |
| 
 | |
| 		// settings based on current method
 | |
| 		$this->prepareClient($method, $client);
 | |
| 
 | |
| 		// authorization data
 | |
| 	//	$data['auth'] = $this->getAuthKey();
 | |
| 		$data['action'] = $method;
 | |
| 
 | |
| 		foreach($data['params'] as $k=>$v)
 | |
| 		{
 | |
| 			$data[$k] = $v;
 | |
| 		}
 | |
| 		unset($data['params']);
 | |
| 
 | |
| 
 | |
| 		// build the request query
 | |
| 		$qry = str_replace(array('s%5B', '%5D'), array('[', ']'), http_build_query($data, null, '&'));
 | |
| 		$url = $this->serviceUrl.'?'.$qry;
 | |
| 		$result = array();
 | |
| 		
 | |
| 		// call it
 | |
| 		try
 | |
| 		{
 | |
| 			$xmlString = $client->loadXMLfile($url,false);
 | |
| 			$xml = new SimpleXMLIterator($xmlString);
 | |
| 			//$result = $client->loadXMLfile($url, 'advanced');
 | |
| 			$result = $this->fetch($method, $xml);
 | |
| 			if(isset($result['exception']))
 | |
| 			{
 | |
| 				$exception = $result['exception'];
 | |
| 				$result['exception'] = array();
 | |
| 				$result['exception']['message'] = "API Exception [call::{$method}]: (#".$exception['code'].") ".$exception['message'];
 | |
| 				$result['exception']['code'] 	= 'API_'.$exception['code'];
 | |
| 			}
 | |
| 		}
 | |
| 		catch(Exception $e)
 | |
| 		{
 | |
| 			$result['exception']['message'] = "Generic Exception [call::{$method}]: (#".$e->getCode().") ".$e->getMessage();
 | |
| 			$result['exception']['code'] 	= 'GEN_'.$e->getCode();
 | |
| 		}
 | |
| 		return $result;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $method
 | |
| 	 * @param $result
 | |
| 	 * @return array|string
 | |
| 	 */
 | |
| 	public function fetch($method, &$result)
 | |
| 	{
 | |
| 		$ret = $this->parse($result);
 | |
| 		$this->fetchParams($ret);
 | |
| 
 | |
| 		switch ($method) 
 | |
| 		{
 | |
| 			// normalize
 | |
| 			case 'getList':
 | |
| 				$ret['data'] = $ret['data']['item'];
 | |
| 			break;
 | |
| 		}
 | |
| 		return $ret;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * New experimental XML parser, will be moved to XML handlers soon
 | |
| 	 * XXX replace xmlClass::xml2array() after this one passes all tests
 | |
| 	 * @param SimpleXmlIterator $xml
 | |
| 	 * @param string $parentName parent node name - used currently for debug only
 | |
| 	 * @return array|string
 | |
| 	 */
 | |
| 	public function parse($xml, $parentName = null)
 | |
| 	{
 | |
| 		$ret = array();
 | |
| 		$tags = array_keys(get_object_vars($xml));
 | |
| 		$count = $xml->count();
 | |
| 		$tcount = count($tags);
 | |
| 
 | |
| 		if($count === 0)
 | |
| 		{
 | |
| 			$attr = (array) $xml->attributes();
 | |
| 			if(!empty($attr))
 | |
| 			{
 | |
| 				$ret['@attributes'] = $attr['@attributes'];
 | |
| 				$ret['@value'] = (string) $xml;
 | |
| 				$ret['@value'] = trim($ret['@value']);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				$ret = (string) $xml;
 | |
| 				$ret = trim($ret);
 | |
| 			}
 | |
| 			return $ret;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * <key>
 | |
| 		 *    <value />
 | |
| 		 *    <value />
 | |
| 		 * </key>
 | |
| 		 */
 | |
| 		if($tcount === 1 && $count > 1)
 | |
| 		{
 | |
| 			foreach($xml as $name => $node)
 | |
| 			{
 | |
| 				$_res = $this->parse($node, $name);
 | |
| 				if(is_string($_res))
 | |
| 				{
 | |
| 					$_res = trim($_res);
 | |
| 				}
 | |
| 
 | |
| 				$ret[$name][] = $this->parse($node, $name);
 | |
| 			}
 | |
| 		}
 | |
| 		// default
 | |
| 		else
 | |
| 		{
 | |
| 			foreach($xml as $name => $node)
 | |
| 			{
 | |
| 				if(in_array($name, $this->_forceArray))
 | |
| 				{
 | |
| 					$_res = $this->parse($node, $name);
 | |
| 					if(is_string($_res))
 | |
| 					{
 | |
| 						$_res = trim($_res);
 | |
| 					}
 | |
| 
 | |
| 					if(empty($_res))
 | |
| 					{
 | |
| 						$ret[$name] = array();
 | |
| 					}
 | |
| 					elseif(is_string($_res)) // empty
 | |
| 					{
 | |
| 						$ret[$name][] = $_res;
 | |
| 					} // string
 | |
| 					else
 | |
| 					{
 | |
| 						if(in_array($name, $this->_forceNumericalArray))
 | |
| 						{
 | |
| 							$ret[$name][] = $_res;
 | |
| 						} //array - controlled force numerical array
 | |
| 						else
 | |
| 						{
 | |
| 							$ret[$name] = $_res;
 | |
| 						} //array, no force
 | |
| 					}
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					$ret[$name] = $this->parse($node, $name);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		$attr = (array) $xml->attributes();
 | |
| 		if(!empty($attr))
 | |
| 		{
 | |
| 			$ret['@attributes'] = $attr['@attributes'];
 | |
| 		}
 | |
| 
 | |
| 		return $ret;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Normalize parameters/attributes
 | |
| 	 * @param array $result parsed to array XML response data
 | |
| 	 */
 | |
| 	public function fetchParams(&$result)
 | |
| 	{
 | |
| 		foreach ($result as $tag => $data) 
 | |
| 		{
 | |
| 			if($tag === 'params')
 | |
| 			{
 | |
| 				foreach ($data['param'] as $i => $param)
 | |
| 				{
 | |
| 					$result[$tag][$param['@attributes']['name']] = $param['@value'];
 | |
| 					unset($result[$tag]['param'][$i]);
 | |
| 				}
 | |
| 				unset($result[$tag]['param']);
 | |
| 			}
 | |
| 			elseif($tag === 'exception')
 | |
| 			{
 | |
| 				$result['exception'] = array('code' => (int) $result['exception']['@attributes']['code'], 'message' => $result['exception']['@value']);
 | |
| 				//unset($result['exception']);
 | |
| 			}
 | |
| 			elseif($tag === '@attributes')
 | |
| 			{
 | |
| 				$result['params'] = $result['@attributes'];
 | |
| 				unset($result['@attributes']);
 | |
| 			}
 | |
| 			elseif(is_array($data))
 | |
| 			{
 | |
| 				$this->fetchParams($result[$tag]);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @param string $method
 | |
| 	 * @param xmlClass $client
 | |
| 	 */
 | |
| 	public function prepareClient($method, &$client)
 | |
| 	{
 | |
| 		switch ($method) 
 | |
| 		{
 | |
| 			case 'getList':
 | |
| 				$this->_forceArray = array('item', 'screenshots', 'image', 'data');
 | |
| 				$this->_forceNumericalArray = array('item', 'image');
 | |
| 				//$client->setOptArrayTags('item,screenshots,image')
 | |
| 				//	->setOptStringTags('icon,folder,version,author,authorURL,date,compatibility,url,thumbnail,featured,livedemo,price,name,description,category,image');
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @return xmlClass
 | |
| 	 */
 | |
| 	public function client()
 | |
| 	{
 | |
| 		return e107::getXml(false);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  */
 | |
| class eAuth
 | |
| {
 | |
| 	
 | |
| 	/**
 | |
| 	 * e107.org manage client credentials (Consumer Key and Secret) URL 
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $eauthConsumerUrl = 'https://e107.org/eauth/client';
 | |
| 	
 | |
| 	/**
 | |
| 	 * URL used to make temporary credential request (Request Token and Secret) to e107.org before the authorization phase
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $eauthRequestUrl = 'https://e107.org/eauth/initialize';
 | |
| 	
 | |
| 	/**
 | |
| 	 * URL used to redirect and authorize the resource owner (user) on e107.org using temporary (request) token
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $eauthAuthorizeUrl = 'https://e107.org/eauth/authorize';
 | |
| 	
 | |
| 	/**
 | |
| 	 * URL used to obtain token credentials (Access Token and Secret) from e107.org using temporary (request) token
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	protected $eauthAccessUrl = 'https://e107.org/eauth/token';
 | |
| 	
 | |
| 	/**
 | |
| 	 * Public client key (generated and obtained from e107.org)
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $eauthConsumerKey = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Client shared secret (generated and obtained from e107.org)
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $eauthConsumerSecret = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Public temporary request token (generated and obtained from e107.org)
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $eauthRequestKey = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Temporary request shared secret (generated and obtained from e107.org)
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $eauthRequestSecret = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Public access token (generated and obtained from e107.org)
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $eauthAccessToken = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Access shared secret (generated and obtained from e107.org)
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $eauthAccessSecret = null;
 | |
| 	
 | |
| 	/**
 | |
| 	 * Request method POST || GET
 | |
| 	 * @var string
 | |
| 	 */
 | |
| 	public $requestMethod = null;
 | |
| 
 | |
| 	/**
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	public function isClient()
 | |
| 	{
 | |
| 		$this->loadSysCredentials();
 | |
| 		return (!empty($this->eauthConsumerKey) && !empty($this->eauthConsumerSecret));
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	public function isInitialized()
 | |
| 	{
 | |
| 		$this->loadSysCredentials();
 | |
| 		return ($this->isClient() && !empty($this->eauthRequestKey) && !empty($this->eauthRequestSecret));
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	public function hasAccess()
 | |
| 	{
 | |
| 		$this->loadSysCredentials();
 | |
| 		return ($this->isClient() && !empty($this->eauthAccessToken) && !empty($this->eauthAccessSecret));
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $method
 | |
| 	 * @param $args
 | |
| 	 * @param $toObject
 | |
| 	 * @return array|stdClass
 | |
| 	 */
 | |
| 	public function serviceAuthData($method, $args, $toObject = true)
 | |
| 	{
 | |
| 		// The client has previously registered with the server and obtained the client identifier dpf43f3p2l4k3l03 and client secret kd94hf93k423kf44. 
 | |
| 		// It has executed the eAuth workflow and obtained an access token nnch734d00sl2jdk and token secret pfkkdhi9sl3r4s00
 | |
| 		
 | |
| 		$date = gmdate('Y-m-d H:i:s');
 | |
| 		$timestamp = $this->gmtTime($date);
 | |
| 		$nonce = $this->nonce($timestamp); // create nonce
 | |
| 		
 | |
| 		$cryptMethod = $this->cryptMethod();
 | |
| 		$authData = array(
 | |
| 			'eauth_consumer_key' 	=> $this->eauthConsumerKey, // (Client Identifier) Application key
 | |
| 			'eauth_token' 			=> $this->eauthAccessToken, // Access Token 
 | |
| 			'eauth_nonce' 			=> $nonce,//'kllo9940pd9333jh' 'nonce' (number used once) string  
 | |
| 			'eauth_timestamp' 		=> $timestamp, // timestamp
 | |
| 			'eauth_signature_method'=> $cryptMethod, // encryption method
 | |
| 			'eauth_version'			=> '1.0', // signature method
 | |
| 		);
 | |
| 		
 | |
| 		// current request parameters
 | |
| 		$args['action'] = $method;
 | |
| 		
 | |
| 		// signature data for building the signature
 | |
| 		$signatureData = $authData;
 | |
| 		
 | |
| 		// add request parameters to the signature array
 | |
| 		$signatureData['eauth_request_params'] = $args;
 | |
| 		
 | |
| 		// sort all
 | |
| 		self::array_kmultisort($signatureData);
 | |
| 		
 | |
| 		// signature base string
 | |
| 		$signatureBaseString = $this->requestMethod.'&'.rawurlencode($this->serviceUrl).'&'.http_build_query($signatureData, false, '&');
 | |
| 		$secretKey = rawurlencode($this->eauthConsumerSecret).'&'.rawurlencode($this->eauthAccessSecret);
 | |
| 		
 | |
| 		// crypt it
 | |
| 		$signature = $this->crypt($signatureBaseString, $secretKey);
 | |
| 		
 | |
| 		//encode it
 | |
| 		$authData['eauth_signature'] = base64_encode($signature);
 | |
| 		if($toObject) return self::toObject($authData);
 | |
| 		
 | |
| 		return $authData;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $array
 | |
| 	 * @return stdClass
 | |
| 	 */
 | |
| 	public static function toObject($array)
 | |
| 	{
 | |
| 		$obj = new stdClass;
 | |
| 		foreach ($array as $key => $value) 
 | |
| 		{
 | |
| 			$obj->$key = $value;
 | |
| 		}
 | |
| 		return $obj;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Load credentials stored in a system file
 | |
| 	 * @param boolean $force
 | |
| 	 * @return eAuth
 | |
| 	 */
 | |
| 	public function loadSysCredentials($force = false)
 | |
| 	{
 | |
| 		if($force || null === $this->eauthConsumerKey)
 | |
| 		{
 | |
| 			$data = e107::getArrayStorage()->load('eauth');
 | |
| 			if(empty($data)) $data = array();
 | |
| 			$this->eauthConsumerKey = varset($data['consumer_key'], '');
 | |
| 			$this->eauthConsumerSecret = varset($data['consumer_secret'], '');
 | |
| 			$this->eauthAccessToken = varset($data['access_token'], '');
 | |
| 			$this->eauthAccessSecret = varset($data['access_secret'], '');
 | |
| 		}
 | |
| 		return $this;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $credentials
 | |
| 	 * @return bool
 | |
| 	 */
 | |
| 	public function storeSysCredentials($credentials = null)
 | |
| 	{
 | |
| 		if(null === $credentials)
 | |
| 		{
 | |
| 			$credentials = array(
 | |
| 				'consumer_key'		=> $this->eauthConsumerKey,
 | |
| 				'consumer_secret'	=> $this->eauthConsumerSecret,
 | |
| 				'access_token'		=> $this->eauthAccessToken,
 | |
| 				'access_secret'		=> $this->eauthAccessSecret,
 | |
| 			);
 | |
| 		}
 | |
| 		if(!is_array($credentials)) return false;
 | |
| 		
 | |
| 		foreach ($credentials as $key => $value) 
 | |
| 		{
 | |
| 			switch ($key) 
 | |
| 			{
 | |
| 				case 'consumer_key':
 | |
| 				case 'consumer_secret':
 | |
| 				case 'access_token':
 | |
| 				case 'access_secret':
 | |
| 					// OK
 | |
| 				break;
 | |
| 				
 | |
| 				default:
 | |
| 					unset($credentials[$key]);
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		return e107::getArrayStorage()->store($credentials, 'eauth');
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Retrieve available system credentials or credential value
 | |
| 	 * @param string $key [optional]
 | |
| 	 * return mixed array of all credentials or string credential value
 | |
| 	 */
 | |
| 	public function getCredentials($key = null)
 | |
| 	{
 | |
| 		$this->loadSysCredentials();
 | |
| 		
 | |
| 		$credentials = array(
 | |
| 			'consumer_key'		=> $this->eauthConsumerKey,
 | |
| 			'consumer_secret'	=> $this->eauthConsumerSecret,
 | |
| 			'access_token'		=> $this->eauthAccessToken,
 | |
| 			'access_secret'		=> $this->eauthAccessSecret,
 | |
| 		);
 | |
| 		if(null !== $key) return varset($credentials[$key], null);
 | |
| 		return $credentials;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $params
 | |
| 	 * @return string
 | |
| 	 * @throws Exception
 | |
| 	 */
 | |
| 	public function toAuthHeader($params)
 | |
| 	{
 | |
| 		$first = true;
 | |
| 		$realm = isset($params['realm']) ? $params['realm'] : null;
 | |
| 		if($realm)
 | |
| 		{
 | |
| 			$out = 'Authorization: eAuth realm="'.rawurlencode($realm).'"';
 | |
| 			$first = false;
 | |
| 		}
 | |
| 		else
 | |
| 			$out = 'Authorization: eAuth';
 | |
| 
 | |
| 		$total = array();
 | |
| 		foreach($params as $k => $v)
 | |
| 		{
 | |
| 			if(strpos($k, "eauth") !== 0) continue;
 | |
| 			if(is_array($v))
 | |
| 			{
 | |
| 				throw new Exception('Arrays not supported in headers', 200);
 | |
| 			}
 | |
| 			$out .= ($first) ? ' ' : ',';
 | |
| 			$out .= rawurlencode($k).'="'.rawurlencode($v).'"';
 | |
| 			$first = false;
 | |
| 		}
 | |
| 		return $out;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	/**
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function cryptMethod()
 | |
| 	{
 | |
| 		return function_exists('hash_hmac') ? 'HMAC-SHA1' : 'SHA1';
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $bits
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	function random($bits = 256)
 | |
| 	{
 | |
| 	    $bytes = ceil($bits / 8);
 | |
| 	    $ret = '';
 | |
| 	    for ($i = 0; $i < $bytes; $i++) 
 | |
| 	    {
 | |
| 	        $ret .= chr(mt_rand(0, 255));
 | |
| 	    }
 | |
| 	    return $ret;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $string
 | |
| 	 * @param $secretKey
 | |
| 	 * @return false|string
 | |
| 	 */
 | |
| 	public function crypt($string, $secretKey)
 | |
| 	{
 | |
| 		$cMethod = $this->cryptMethod();
 | |
| 		// Append secret if it's sha1
 | |
| 		if($cMethod == 'SHA1')
 | |
| 		{
 | |
| 			return sha1($string.$secretKey);
 | |
| 		}
 | |
| 		// use secret key if HMAC-SHA1
 | |
| 		return hash_hmac('sha1', $string, $secretKey);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $timestamp
 | |
| 	 * @return false|string
 | |
| 	 */
 | |
| 	public function nonce($timestamp)
 | |
| 	{
 | |
| 		return $this->crypt($this->random().$timestamp, $this->eauthAccessSecret.$this->eauthConsumerSecret);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $string
 | |
| 	 * @return false|int
 | |
| 	 */
 | |
| 	public function gmtTime($string)
 | |
| 	{
 | |
| 		$ret = false;
 | |
| 		// mask - Y-m-d H:i:s
 | |
| 		if(preg_match('#(.*?)-(.*?)-(.*?) (.*?):(.*?):(.*?)$#', $string, $matches))
 | |
| 		{
 | |
| 			$ret = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
 | |
| 		}
 | |
| 		return $ret;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $array
 | |
| 	 * @param $order
 | |
| 	 * @return void
 | |
| 	 */
 | |
| 	public static function array_kmultisort(&$array, $order = 'asc')
 | |
| 	{
 | |
| 		$func = $order == 'asc' ? 'ksort' : 'krsort';
 | |
| 		$func($array);
 | |
| 		foreach ($array as $key => $value) 
 | |
| 		{
 | |
| 			if(is_array($value))
 | |
| 			{
 | |
| 				self::array_kmultisort($value, $order);
 | |
| 				$array[$key] = $value;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |