Created
July 9, 2013 08:58
-
-
Save larseirik/5955815 to your computer and use it in GitHub Desktop.
RemoteCaller - Refactored.
Idea is to simplify the api and make the class eaiser to read. Regression issues.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class RemoteCaller { | |
private $username="system"; | |
private $password="fcbea236d39e3e4ac4c4e6727248540276930d2c5415ae11209572a2910105bd1728854bd47e47e869e87abd28cc8242361ef84f23ac0d0fee46a8f04a82d0fa"; | |
const SERVICE_DOWN = 500; | |
private $domain; | |
private $service_list; | |
private $port; | |
private $store_local_data = false; | |
private $storage_path; | |
private $contentType = ""; | |
private $acceptContentType=""; | |
private $httpMethod = null; | |
private $service_with_school_param=array(); | |
private $protocol; | |
private $token; | |
const DATA_FORMAT_JSON = "application/json"; | |
const DATA_FORMAT_XML ="application/xml"; | |
const HTTP_POST = "POST"; | |
const HTTP_DELETE="DELETE"; | |
public function __construct($username=null,$password=null) { | |
if($username){ | |
$this->username=$username; | |
} | |
if($password){ | |
$this->password=$password; | |
} | |
$lokusini = eZINI::instance( 'lokus.ini' ); | |
$this->port = $lokusini->variable( 'ServicesURL', 'RemoteServicesPort' ); | |
$this->domain = $lokusini->variable( 'ServicesURL', 'RemoteServicesDomain' ); | |
if($lokusini->hasVariable("ServicesURL", 'HttpProtocol')){ | |
$this->protocol = $lokusini->variable("ServicesURL",'HttpProtocol'); | |
} | |
if(!$this->protocol){ | |
if ($this->port == 443) { | |
$this->protocol = "https"; | |
} else { | |
$this->protocol="http"; | |
} | |
} | |
$this->service_list = $lokusini->variable( 'ServicesURL', 'RemoteServicesList' ); | |
$this->service_with_school_param = $lokusini->variable( 'ServicesURL', 'AppendQuerySchoolParamToRemoteService' ); | |
$this->store_local_data = $lokusini->variable( 'DebugSettings', 'StoreRemoteServicesData' ) == 'enabled'; | |
$this->storage_path = trim( $lokusini->variable( 'DebugSettings', 'StorageDir' ), '/' ); | |
} | |
public function __destruct() { | |
try { | |
$this->logOutOfOpenAM(); | |
} catch (Exception $e) { | |
// ignore | |
} | |
} | |
/** | |
* Use this to set the returned dataformat for the called service | |
* @example RemoteCaller::DATA_FORMAT_JSON or RemoteCaller::DATA_FORMAT_XML | |
* | |
*/ | |
public function setAcceptType($acceptType){ | |
$this->acceptContentType=$acceptType; | |
} | |
public function setContentType($contentType){ | |
$this->contentType=$contentType; | |
} | |
public function setHttpMethod($method){ | |
$this->httpMethod=$method; | |
} | |
public function logOnToOpenAM(){ | |
if ( LokusUrls::isDebugMode() ) { | |
return true; | |
} | |
$url = LokusUrls::getAuthenticationURL(); | |
$this->port = LokusUrls::getOpenAmPort(); | |
$url.="?username=".$this->username."&password=".$this->password; | |
//empty cookie until we have a valid token from openAM | |
$response = $this->processCurlRequest($url,""); | |
eZLog::write("entered authenticatewithopenam " . $response,"remotecaller.log"); | |
if(is_array($response) && array_key_exists('error', $response)){ | |
return false; | |
} | |
$this->token=$response; | |
return true; | |
} | |
public function logOutOfOpenAM(){ | |
if ( !LokusUrls::isDebugMode() && !empty($this->token) ) { | |
$url = LokusUrls::getLogoutFromOpenAMRequestURL(); | |
$this->port = LokusUrls::getOpenAmPort(); | |
$url.="?subjectid=".$this->getSystemToken(); | |
$response = $this->processCurlRequest($url,$this->getSystemCookie()); | |
} | |
$this->token = null; | |
} | |
public function isLoggedIn() { | |
if ( !LokusUrls::isDebugMode() && !empty( $this->token ) ) { | |
$url = LokusUrls::getOpenAMIsLoggedInUrl(); | |
$this->port = LokusUrls::getOpenAmPort(); | |
$url .= "?tokenid={$this->token}"; | |
$response = $this->processCurlRequest($url,$this->getSystemCookie()); | |
//openAM will return a http status code and this is inserted to an array in processCurlRequest | |
if(is_array($response) && array_key_exists('error', $response)){ | |
return false; | |
} | |
} | |
return true; | |
} | |
private function getHttpHeaders(){ | |
$httpHeaders = array(); | |
if($this->acceptContentType && $this->acceptContentType!=null){ | |
$httpHeaders[]="Accept:".$this->acceptContentType; | |
} | |
if($this->contentType!=null){ | |
$httpHeaders[]="Content-Type:".$this->contentType; | |
} | |
return $httpHeaders; | |
} | |
public function setPort($port){ | |
$this->port=$port; | |
} | |
public function getUsername() { | |
return $this->username; | |
} | |
public function getPassword() { | |
return $this->password; | |
} | |
// Returning token value of current OpenAM cookie | |
private function getSystemToken() { | |
if ( empty( $this->token ) ) { | |
return false; | |
} | |
return $this->token; | |
} | |
public function callService( $service, array $url_params = array(), array $params = array() ) { | |
if ( isset( $this->service_list[$service] ) ) { | |
$path = $this->service_list[$service]; | |
$lokusini = eZINI::instance("lokus.ini"); | |
$this->port = $lokusini->variable( 'ServicesURL', 'RemoteServicesPort' ); | |
$params = $this->addSchoolParamIfNeeded($service, $params); | |
if ( !empty( $url_params ) ) | |
{ | |
$path .= '/' . implode( '/', $url_params ); | |
} | |
if ( LokusUrls::isDebugMode() ) { | |
$result = $this->getLocalJSON( $path, $url_params, $params ); | |
} else { | |
$this->port = ( $this->port != 80 ) ? ':' . $this->port : ''; | |
$url = "{$this->protocol}://{$this->domain}{$this->port}/$path"; | |
eZLog::write("SYstemCookie " . $this->getSystemCookie(),"remotecaller.log"); | |
$result = $this->processCurlRequest($url, $this->getSystemCookie(),$params); | |
if ( $this->store_local_data ) | |
{ | |
$this->storeLocalJSON( $path, $url_params, $params, $result ); | |
} | |
} | |
} else { | |
eZDebug::writeError( "Remote service {$this->$service} not found"); | |
return array( 'error'=>self::SERVICE_DOWN ); | |
} | |
return $result; | |
} | |
/* this function currently does not support custom getParameters at current time | |
* | |
*/ | |
public function updateXMLService( $service, XMLWriteable $xmlWriteableObject,array $urlParams = array(),array $requestParams = array()) { | |
if ( isset( $this->service_list[$service] ) ) { | |
$this->path = $this->service_list[$service]; | |
$lokusini = eZINI::instance("lokus.ini"); | |
$this->port = $lokusini->variable( 'ServicesURL', 'RemoteServicesPort' ); | |
$this->port = ( $this->port != 80 ) ? ':' . $this->port : ''; | |
$params = $this->addSchoolParamIfNeeded($service,$requestParams); | |
if(!empty($urlParams)){ | |
$url.="/".implode("/", $urlParams); | |
} | |
if ( LokusUrls::isDebugMode() ) { | |
$result = $this->getLocalJSON( $path, array(), array() ); | |
} else { | |
$url = "{$this->protocol}://{$this->domain}{$this->port}/{$this->path}"; | |
$postParams = $xmlWriteableObject->prepareXML(); | |
if(!$this->httpMethod){ | |
$this->httpMethod=self::HTTP_POST; | |
} | |
if(!$this->contentType){ | |
$this->contentType=self::DATA_FORMAT_XML; | |
} | |
$result=$this->processCurlRequest($url,LokusUrls::getOpenAmCookieValue(),$params, $postParams); | |
} | |
} else { | |
eZDebug::writeError( "Remote service '$service' not found"); | |
return array( 'error'=>self::SERVICE_DOWN ); | |
} | |
return $result; | |
} | |
/** | |
* Method verifies user's credentials in openAM | |
* | |
* @param $username | |
* @param $password | |
* @param $realm | |
* @return bool | |
*/ | |
public function verifyGivenUserWithOpenAM($username,$password, $realm){ | |
$url = LokusUrls::getAuthenticationURL(); | |
$this->port = LokusUrls::getOpenAmPort(); | |
$url .= "?username=" . $username . "&password=" . $password . "&uri=realm=" . $realm; | |
$response = $this->processCurlRequest($url,$this->getSystemCookie()); | |
return (!is_array($response) && substr($response,0,5) === 'token') ? true : false; | |
} | |
/* | |
* Note that user has not been set before the user actually receives data from backend service | |
* hence we need to check if the user variable exists | |
*/ | |
private function addSchoolParamIfNeeded($service, array $params=array()){ | |
if(in_array($service,$this->service_with_school_param)){ | |
$http = eZHTTPTool::instance(); | |
$user = $http->sessionVariable("user"); | |
if($user){ | |
$activeOrganization = $user->getActiveOrganization(); | |
$schoolParam = array(); | |
if(isset($activeOrganization["number"])){ | |
$schoolParam = array("school"=>$activeOrganization["number"]); | |
} | |
$params = array_merge($params,$schoolParam); | |
} | |
} | |
return $params; | |
} | |
private function extractToken($token) { | |
list( $cookie_name, $token ) = explode( '=', token ); | |
if ( empty( $token ) ) { | |
return false; | |
} | |
return $token; | |
} | |
private function getSystemCookie(){ | |
if(strlen($this->token)<1){ | |
return array('error',"the session token is invalid"); | |
} | |
$this->token = getToken() | |
return "iPlanetDirectoryPro=".$this->token; | |
} | |
private function callCurl( $ch, $url ) { | |
$response = curl_exec($ch); | |
$statusCode=curl_getinfo($ch,CURLINFO_HTTP_CODE); | |
curl_close($ch); | |
// Check for HTTP result status above 300 (any errors) | |
if($statusCode>300){ | |
eZDebug::writeError("Received status code " . $statusCode . " when trying to connect to " . $url ); | |
return array('error'=>$statusCode); | |
} | |
else if($response===false){ | |
eZDebug::writeError("No HTTP reponse received!Service " . $url ." is down"); | |
return array('error'=>self::SERVICE_DOWN); | |
} | |
return $response; | |
} | |
private function processCurlRequest($url,$cookie,array $getParams=array(),$postParams=array()){ | |
$ch = curl_init(); | |
if($this->port>0){ | |
curl_setopt($ch,CURLOPT_PORT,$this->port); | |
} | |
if($cookie){ | |
curl_setopt($ch,CURLOPT_COOKIE,trim($cookie)); | |
} | |
if(count($getParams)>0){ | |
$get_array = array(); | |
foreach ( $getParams as $name => $param ) | |
{ | |
$get_array[] = "$name=$param"; | |
} | |
$url.= '?' . implode( '&', $get_array ); | |
} | |
curl_setopt($ch,CURLOPT_URL,$url); | |
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); | |
if($this->httpMethod==self::HTTP_POST && !$this->contentType){ | |
curl_setopt($ch,CURLOPT_POST,true); | |
curl_setopt($ch,CURLOPT_POSTFIELDS,array()); | |
} | |
else if($this->contentType and $this->httpMethod==self::HTTP_POST){ | |
eZLog::write($this->contentType ." method = " . $this->httpMethod,"registerlogger.log"); | |
eZLog::write($postParams,"registerlogger.log"); | |
curl_setopt($ch,CURLOPT_POST,true); | |
curl_setopt($ch,CURLOPT_POSTFIELDS,$postParams); | |
} | |
if($this->httpMethod == self::HTTP_DELETE){ | |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,$this->httpMethod); | |
} | |
$httpHeaders = $this->getHttpHeaders(); | |
if(count($httpHeaders)>0){ | |
curl_setopt($ch, CURLOPT_HTTPHEADER,$httpHeaders); | |
} | |
return $this->callCurl( $ch, $url ); | |
} | |
private function getLocalJSON( $path, $url_params, $params ) { | |
$filename = hash( 'md5', implode( ',', array( $path, implode( ',', $url_params ), implode( ',', $params ) ) ) ) . '.cache'; | |
if ( is_file( "{$this->storage_path}/$filename" ) ) { | |
$serial_data = file_get_contents( "{$this->storage_path}/$filename" ); | |
$data = unserialize( $serial_data ); | |
} else { | |
eZDebug::writeError( "Local data file '{$this->storage_path}/$filename' from remote services not found"); | |
return array( 'error'=>self::SERVICE_DOWN ); | |
} | |
return $data['result']; | |
} | |
private function storeLocalJSON( $path, $url_params, $params, $result ) { | |
eZDir::mkdir( $this->storage_path, false, true ); | |
$filename = hash( 'md5', implode( ',', array( $path, implode( ',', $url_params ), implode( ',', $params ) ) ) ) . '.cache'; | |
$serial_data = serialize( array( 'path' => $path, | |
'url_params' => $url_params, | |
'params' => $params, | |
'result' => $result ) ); | |
$status = file_put_contents( "{$this->storage_path}/$filename", $serial_data ); | |
if ( $status === false ) { | |
eZDebug::writeError( "Failed writing to remote services local file '{$this->storage_path}/$filename'"); | |
} | |
return $status; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment