<?php
/**
 * A very basic REST-api client
 * 
 * @version 1.1
 * 
 */
class restapi_client {
	
	protected $_sEndpoint = '';

	protected $_sUrl = '';
	
	protected $_aHeaders = array();
	
	protected $_iClientTimeOut = 10;
	
	protected $_oResponse = false;
	
	/**
	 * construct
	 * 
	 * @param	$sEndpoint				string		
	 * @param	$sAuthHeaderKey		string
	 * @param	$sAuthHeaderValue	string
	 * @return	void
	 * 
	 */
	public function __construct($sEndpoint, $sAuthHeaderKey = '', $sAuthHeaderValue = ''){
		
		$this->_sEndpoint = $sEndpoint;
		
		if (!empty($sAuthHeaderKey) && !empty($sAuthHeaderValue)){

			$this->_aHeaders = [ 'Content-Type: application/json; charset=utf-8', $sAuthHeaderKey . ': ' . $sAuthHeaderValue ];

		} else {

			$this->_aHeaders = [ 'Content-Type: application/json; charset=utf-8' ];

		}
		
	}

	/**
	 * POST method
	 * 
	 * @param	$sEndpoint	string
	 * @param	$oParams	object/string
	 * @param	$bEncode	boolean		false => data already json-encoded
	 * @return	void
	 * 
	 */
	public function post($sEndpoint, $oParams = false, $bEncode = true){
		
		$sUrl = rtrim($this->_sEndpoint, '/') . '/' . ltrim($sEndpoint, '/');
		
		$sParams = '';
		
		if ($oParams !== false){
		
			$bEncode === true ? $sParams = json_encode($oParams, JSON_UNESCAPED_SLASHES) : $sParams = $oParams;
			
		}

		$this->_sUrl = $sUrl;

		$oCurl = curl_init();
		curl_setopt($oCurl, CURLOPT_URL, $sUrl);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->_iClientTimeOut);
		curl_setopt($oCurl, CURLOPT_POST, true);
		
		if (!empty($sParams)){
		
			curl_setopt($oCurl, CURLOPT_POSTFIELDS, $sParams);
			
		}
		
		curl_setopt($oCurl, CURLOPT_HTTPHEADER, $this->_aHeaders);
		curl_setopt($oCurl, CURLOPT_HEADER, true);
		
		$oResponse = new stdClass();
		$oResponse->raw = curl_exec($oCurl);
		$oResponse->error = curl_errno($oCurl);
		$oResponse->info = curl_getinfo($oCurl);
		$oResponse->headers = mb_substr($oResponse->raw, 0, $oResponse->info['header_size']);
		$oResponse->json = mb_substr($oResponse->raw, $oResponse->info['header_size']);
		$oResponse->result = json_decode($oResponse->json);
		
		$this->_oResponse = $oResponse;

	}
	
	/**
	 * PUT method
	 * 
	 * @param	$sEndpoint	string
	 * @param	$oParams	object
	 * @param	$bEncode	boolean		false => data already json-encoded
	 * @return	void
	 * 
	 */
	public function put($sEndpoint, $oParams = false, $bEncode = true){
		
		$sUrl = rtrim($this->_sEndpoint, '/') . '/' . ltrim($sEndpoint, '/');
		
		$sParams = '';
		
		if ($oParams !== false){
		
			$bEncode === true ? $sParams = json_encode($oParams, JSON_UNESCAPED_SLASHES) : $sParams = $oParams;
			
		}

		$this->_sUrl = $sUrl;

		$oCurl = curl_init();
		curl_setopt($oCurl, CURLOPT_URL, $sUrl);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->_iClientTimeOut);
		curl_setopt($oCurl, CURLOPT_CUSTOMREQUEST, 'PUT');
		
		if (!empty($sParams)){
		
			curl_setopt($oCurl, CURLOPT_POSTFIELDS, $sParams);
			
		}
		
		curl_setopt($oCurl, CURLOPT_HTTPHEADER, $this->_aHeaders);
		curl_setopt($oCurl, CURLOPT_HEADER, true);
		
		$oResponse = new stdClass();
		$oResponse->raw = curl_exec($oCurl);
		$oResponse->error = curl_errno($oCurl);
		$oResponse->info = curl_getinfo($oCurl);
		$oResponse->headers = mb_substr($oResponse->raw, 0, $oResponse->info['header_size']);
		$oResponse->json = mb_substr($oResponse->raw, $oResponse->info['header_size']);
		$oResponse->result = json_decode($oResponse->json);
		
		$this->_oResponse = $oResponse;

	}	
	
	/**
	 * PATCH method
	 * 
	 * @param	$sEndpoint	string
	 * @param	$oParams	object
	 * @param	$bEncode	boolean		false => data already json-encoded
	 * @return	void
	 * 
	 */
	public function patch($sEndpoint, $oParams = false, $bEncode = true){

		$sUrl = rtrim($this->_sEndpoint, '/') . '/' . ltrim($sEndpoint, '/');

		$sParams = '';

		if ($oParams !== false){

			$bEncode === true ? $sParams = json_encode($oParams, JSON_UNESCAPED_SLASHES) : $sParams = $oParams;

		}

		$this->_sUrl = $sUrl;

		$oCurl = curl_init();
		curl_setopt($oCurl, CURLOPT_URL, $sUrl);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->_iClientTimeOut);
		curl_setopt($oCurl, CURLOPT_CUSTOMREQUEST, 'PATCH');

		if (!empty($sParams)){

			curl_setopt($oCurl, CURLOPT_POSTFIELDS, $sParams);

		}

		curl_setopt($oCurl, CURLOPT_HTTPHEADER, $this->_aHeaders);
		curl_setopt($oCurl, CURLOPT_HEADER, true);

		$oResponse = new stdClass();
		$oResponse->raw = curl_exec($oCurl);
		$oResponse->error = curl_errno($oCurl);
		$oResponse->info = curl_getinfo($oCurl);
		$oResponse->headers = mb_substr($oResponse->raw, 0, $oResponse->info['header_size']);
		$oResponse->json = mb_substr($oResponse->raw, $oResponse->info['header_size']);
		$oResponse->result = json_decode($oResponse->json);

		$this->_oResponse = $oResponse;

	}	

	/**
	 * DELETE method
	 * 
	 * @param	$sEndpoint	string
	 * @param	$oParams	object
	 * @param	$bEncode	boolean		false => data already json-encoded
	 * @return	void
	 * 
	 */
	public function delete($sEndpoint, $oParams = false, $bEncode = true){
		
		$sUrl = rtrim($this->_sEndpoint, '/') . '/' . ltrim($sEndpoint, '/');
		
		$sParams = '';
		
		if ($oParams !== false){
		
			$bEncode === true ? $sParams = json_encode($oParams, JSON_UNESCAPED_SLASHES) : $sParams = $oParams;
			
		}

		$this->_sUrl = $sUrl;

		$oCurl = curl_init();
		curl_setopt($oCurl, CURLOPT_URL, $sUrl);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->_iClientTimeOut);
		curl_setopt($oCurl, CURLOPT_CUSTOMREQUEST, 'DELETE');
		
		if (!empty($sParams)){
		
			curl_setopt($oCurl, CURLOPT_POSTFIELDS, $sParams);
			
		}
		
		curl_setopt($oCurl, CURLOPT_HTTPHEADER, $this->_aHeaders);
		curl_setopt($oCurl, CURLOPT_HEADER, true);
		
		$oResponse = new stdClass();
		$oResponse->raw = curl_exec($oCurl);
		$oResponse->error = curl_errno($oCurl);
		$oResponse->info = curl_getinfo($oCurl);
		$oResponse->headers = mb_substr($oResponse->raw, 0, $oResponse->info['header_size']);
		$oResponse->json = mb_substr($oResponse->raw, $oResponse->info['header_size']);
		$oResponse->result = json_decode($oResponse->json);
		
		$this->_oResponse = $oResponse;

	}	
	
	/**
	 * GET method
	 * 
	 * @param	$sEndpoint	string
	 * @param	$oParams	object
	 * @return	void
	 * 
	 */
	public function get($sEndpoint, $oParams = false){
		
		$sUrl = rtrim($this->_sEndpoint, '/') . '/' . ltrim($sEndpoint, '/');
		
		if ($oParams !== false && stripos($sUrl, '?') === false){

			$sUrl .= '?' . http_build_query($oParams);		
			
		}

		$this->_sUrl = $sUrl;

		$oCurl = curl_init();
		curl_setopt($oCurl, CURLOPT_URL, $sUrl);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->_iClientTimeOut);
		curl_setopt($oCurl, CURLOPT_HTTPGET, true);
		curl_setopt($oCurl, CURLOPT_HTTPHEADER, $this->_aHeaders);
		curl_setopt($oCurl, CURLOPT_HEADER, true);

		$oResponse = new stdClass();
		$oResponse->raw = curl_exec($oCurl);
		$oResponse->error = curl_errno($oCurl);
		$oResponse->info = curl_getinfo($oCurl);
		$oResponse->headers = mb_substr($oResponse->raw, 0, $oResponse->info['header_size']);
		$oResponse->json = mb_substr($oResponse->raw, $oResponse->info['header_size']);
		$oResponse->result = json_decode($oResponse->json);
		
		$this->_oResponse = $oResponse;
		
	}

	/**
	 * Return client raw response
	 * 
	 * @return boolean/string
	 * 
	 */
	public function client_response_raw(){
		
		if ($this->_oResponse === false){
			
			return false;
			
		}
		
		return $this->_oResponse->raw;
		
	}
	
	/**
	 * Return client error
	 * 
	 * @return boolean/string
	 * 
	 */
	public function client_response_error(){
		
		if ($this->_oResponse === false){
			
			return false;
			
		}
		
		return $this->_oResponse->error;
		
	}

	/**
	 * Return client info
	 * 
	 * @return boolean/string
	 * 
	 */
	public function client_response_info(){
		
		if ($this->_oResponse === false){
			
			return false;
			
		}
		
		return $this->_oResponse->info;
		
	}	
	
	/**
	 * Return client endpoint
	 * 
	 * @return array
	 * 
	 */
	public function client_endpoint(){
		
		return $this->_sUrl;
		
	}		

	/**
	 * Return client request-headers
	 * 
	 * @return array
	 * 
	 */
	public function client_request_headers(){
		
		return $this->_aHeaders;
		
	}		

	/**
	 * Return client headers
	 * 
	 * @return boolean/string
	 * 
	 */
	public function client_response_headers(){
		
		if ($this->_oResponse === false){
			
			return false;
			
		}
		
		return $this->_oResponse->headers;
		
	}		

	/**
	 * Return client json result
	 * 
	 * @return boolean/string
	 * 
	 */
	public function client_response_json(){
		
		if ($this->_oResponse === false){
			
			return false;
			
		}
		
		return $this->_oResponse->json;
		
	}			

	/**
	 * Return client result
	 * 
	 * @return boolean/string
	 * 
	 */
	public function client_response_result(){
		
		if ($this->_oResponse === false){
			
			return false;
			
		}
		
		return $this->_oResponse->result;
		
	}			
	
}