Skip to content

Instantly share code, notes, and snippets.

@larseirik
Created July 9, 2013 08:58
Show Gist options
  • Save larseirik/5955815 to your computer and use it in GitHub Desktop.
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.
<?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