2013-05-09 09:11:17 +00:00
< ? php
/*
* oauth_client . php
*
* @ ( #) $Id: oauth_client.php,v 1.58 2013/04/11 09:33:16 mlemos Exp $
*
*/
/*
{ metadocument } < ? xml version = " 1.0 " encoding = " ISO-8859-1 " ?>
< class >
< package > net . manuellemos . oauth </ package >
< version >@ ( #) $Id: oauth_client.php,v 1.58 2013/04/11 09:33:16 mlemos Exp $</version>
< copyright > Copyright <EFBFBD> ( C ) Manuel Lemos 2012 </ copyright >
< title > OAuth client </ title >
< author > Manuel Lemos </ author >
< authoraddress > mlemos - at - acm . org </ authoraddress >
< documentation >
< idiom > en </ idiom >
< purpose > This class serves two main purposes :< paragraphbreak />
1 ) Implement the OAuth protocol to retrieve a token from a server to
authorize the access to an API on behalf of the current
user .< paragraphbreak />
2 ) Perform calls to a Web services API using a token previously
obtained using this class or a token provided some other way by the
Web services provider .</ purpose >
< usage > Regardless of your purposes , you always need to start calling
the class < functionlink > Initialize </ functionlink > function after
initializing setup variables . After you are done with the class ,
always call the < functionlink > Finalize </ functionlink > function at
the end .< paragraphbreak />
This class supports either OAuth protocol versions 1.0 , 1.0 a and
2.0 . It abstracts the differences between these protocol versions ,
so the class usage is the same independently of the OAuth
version of the server .< paragraphbreak />
The class also provides built - in support to several popular OAuth
servers , so you do not have to manually configure all the details to
access those servers . Just set the
< variablelink > server </ variablelink > variable to configure the class
to access one of the built - in supported servers .< paragraphbreak />
If you need to access one type of server that is not yet directly
supported by the class , you need to configure it explicitly setting
the variables : < variablelink > oauth_version </ variablelink > ,
< variablelink > url_parameters </ variablelink > ,
< variablelink > authorization_header </ variablelink > ,
< variablelink > request_token_url </ variablelink > ,
< variablelink > dialog_url </ variablelink > ,
< variablelink > offline_dialog_url </ variablelink > ,
< variablelink > append_state_to_redirect_uri </ variablelink > and
< variablelink > access_token_url </ variablelink >.< paragraphbreak />
Before proceeding to the actual OAuth authorization process , you
need to have registered your application with the OAuth server . The
registration provides you values to set the variables
< variablelink > client_id </ variablelink > and
< variablelink > client_secret </ variablelink >.< paragraphbreak />
You also need to set the variables
< variablelink > redirect_uri </ variablelink > and
< variablelink > scope </ variablelink > before calling the
< functionlink > Process </ functionlink > function to make the class
perform the necessary interactions with the OAuth
server .< paragraphbreak />
The OAuth protocol involves multiple steps that include redirection
to the OAuth server . There it asks permission to the current user to
grant your application access to APIs on his / her behalf . When there
is a redirection , the class will set the
< variablelink > exit </ variablelink > variable to
< booleanvalue > 1 </ booleanvalue >. Then your script should exit
immediately without outputting anything .< paragraphbreak />
When the OAuth access token is successfully obtained , the following
variables are set by the class with the obtained values :
< variablelink > access_token </ variablelink > ,
< variablelink > access_token_secret </ variablelink > ,
< variablelink > access_token_expiry </ variablelink > ,
< variablelink > access_token_type </ variablelink >. You may want to
store these values to use them later when calling the server
APIs .< paragraphbreak />
If there was a problem during OAuth authorization process , check the
variable < variablelink > authorization_error </ variablelink > to
determine the reason .< paragraphbreak />
Once you get the access token , you can call the server APIs using
the < functionlink > CallAPI </ functionlink > function . Check the
< variablelink > access_token_error </ variablelink > variable to
determine if there was an error when trying to to call the
API .< paragraphbreak />
If for some reason the user has revoked the access to your
application , you need to ask the user to authorize your application
again . First you may need to call the function
< functionlink > ResetAccessToken </ functionlink > to reset the value of
the access token that may be cached in session variables .</ usage >
</ documentation >
{ / metadocument }
*/
class oauth_client_class
{
/*
{ metadocument }
< variable >
< name > error </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Store the message that is returned when an error
occurs .</ purpose >
< usage > Check this variable to understand what happened when a call to
any of the class functions has failed .< paragraphbreak />
This class uses cumulative error handling . This means that if one
class functions that may fail is called and this variable was
already set to an error message due to a failure in a previous call
to the same or other function , the function will also fail and does
not do anything .< paragraphbreak />
This allows programs using this class to safely call several
functions that may fail and only check the failure condition after
the last function call .< paragraphbreak />
Just set this variable to an empty string to clear the error
condition .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $error = '' ;
/*
{ metadocument }
< variable >
< name > debug </ name >
< type > BOOLEAN </ type >
< value > 0 </ value >
< documentation >
< purpose > Control whether debug output is enabled </ purpose >
< usage > Set this variable to < booleanvalue > 1 </ booleanvalue > if you
need to check what is going on during calls to the class . When
enabled , the debug output goes either to the variable
< variablelink > debug_output </ variablelink > and the PHP error log .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $debug = false ;
/*
{ metadocument }
< variable >
< name > debug_http </ name >
< type > BOOLEAN </ type >
< value > 0 </ value >
< documentation >
< purpose > Control whether the dialog with the remote Web server
should also be logged .</ purpose >
< usage > Set this variable to < booleanvalue > 1 </ booleanvalue > if you
want to inspect the data exchange with the OAuth server .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $debug_http = false ;
/*
{ metadocument }
< variable >
< name > exit </ name >
< type > BOOLEAN </ type >
< value > 0 </ value >
< documentation >
< purpose > Determine if the current script should be exited .</ purpose >
< usage > Check this variable after calling the
< functionlink > Process </ functionlink > function and exit your script
immediately if the variable is set to
< booleanvalue > 1 </ booleanvalue >.</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $exit = false ;
/*
{ metadocument }
< variable >
< name > debug_output </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Capture the debug output generated by the class </ purpose >
< usage > Inspect this variable if you need to see what happened during
the class function calls .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $debug_output = '' ;
/*
{ metadocument }
< variable >
< name > debug_prefix </ name >
< type > STRING </ type >
< value > OAuth client : </ value >
< documentation >
< purpose > Mark the lines of the debug output to identify actions
performed by this class .</ purpose >
< usage > Change this variable if you prefer the debug output lines to
be prefixed with a different text .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $debug_prefix = 'OAuth client: ' ;
/*
{ metadocument }
< variable >
< name > server </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Identify the type of OAuth server to access .</ purpose >
< usage > The class provides built - in support to several types of OAuth
servers . This means that the class can automatically initialize
several configuration variables just by setting this server
variable .< paragraphbreak />
Currently it supports the following servers :
< stringvalue > Bitbucket </ stringvalue > ,
< stringvalue > Box </ stringvalue > ,
< stringvalue > Dropbox </ stringvalue > ,
< stringvalue > Eventful </ stringvalue > ,
< stringvalue > Facebook </ stringvalue > ,
< stringvalue > Fitbit </ stringvalue > ,
< stringvalue > Flickr </ stringvalue > ,
< stringvalue > Foursquare </ stringvalue > ,
< stringvalue > github </ stringvalue > ,
< stringvalue > Google </ stringvalue > ,
< stringvalue > Instagram </ stringvalue > ,
< stringvalue > LinkedIn </ stringvalue > ,
< stringvalue > Microsoft </ stringvalue > ,
< stringvalue > Scoop . it </ stringvalue > ,
< stringvalue > StockTwits </ stringvalue > ,
< stringvalue > Tumblr </ stringvalue > ,
< stringvalue > Twitter </ stringvalue > ,
< stringvalue > XING </ stringvalue > and
< stringvalue > Yahoo </ stringvalue >. Please contact the author if you
would like to ask to add built - in support for other types of OAuth
servers .< paragraphbreak />
If you want to access other types of OAuth servers that are not
yet supported , set this variable to an empty string and configure
other variables with values specific to those servers .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $server = '' ;
/*
{ metadocument }
< variable >
< name > request_token_url </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > URL of the OAuth server to request the initial token for
OAuth 1.0 and 1.0 a servers .</ purpose >
< usage > Set this variable to the OAuth request token URL when you are
not accessing one of the built - in supported OAuth
servers .< paragraphbreak />
For OAuth 1.0 and 1.0 a servers , the request token URL can have
certain marks that will act as template placeholders which will be
replaced with given values before requesting the authorization
token . Currently it supports the following placeholder
marks :< paragraphbreak />
{ SCOPE } - scope of the requested permissions to the granted by the
OAuth server with the user permissions </ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $request_token_url = '' ;
/*
{ metadocument }
< variable >
< name > dialog_url </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > URL of the OAuth server to redirect the browser so the user
can grant access to your application .</ purpose >
< usage > Set this variable to the OAuth request token URL when you are
not accessing one of the built - in supported OAuth servers .< paragraphbreak />
For certain servers , the dialog URL can have certain marks that
will act as template placeholders which will be replaced with
values defined before redirecting the users browser . Currently it
supports the following placeholder marks :< paragraphbreak />
{ REDIRECT_URI } - URL to redirect when returning from the OAuth
server authorization page < paragraphbreak />
{ CLIENT_ID } - client application identifier registered at the
server < paragraphbreak />
{ SCOPE } - scope of the requested permissions to the granted by the
OAuth server with the user permissions < paragraphbreak />
{ STATE } - identifier of the OAuth session state </ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $dialog_url = '' ;
/*
{ metadocument }
< variable >
< name > offline_dialog_url </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > URL of the OAuth server to redirect the browser so the user
can grant access to your application when offline access is
requested .</ purpose >
< usage > Set this variable to the OAuth request token URL when you are
not accessing one of the built - in supported OAuth servers and the
OAuth server supports offline access .< paragraphbreak />
It should have the same format as the
< variablelink > dialog_url </ variablelink > variable .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $offline_dialog_url = '' ;
/*
{ metadocument }
< variable >
< name > append_state_to_redirect_uri </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Pass the OAuth session state in a variable with a different
name to work around implementation bugs of certain OAuth
servers </ purpose >
< usage > Set this variable when you are not accessing one of the
built - in supported OAuth servers if the OAuth server has a bug
that makes it not pass back the OAuth state identifier in a
request variable named state .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $append_state_to_redirect_uri = '' ;
/*
{ metadocument }
< variable >
< name > access_token_url </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > OAuth server URL that will return the access token
URL .</ purpose >
< usage > Set this variable to the OAuth access token URL when you are
not accessing one of the built - in supported OAuth servers .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $access_token_url = '' ;
/*
{ metadocument }
< variable >
< name > oauth_version </ name >
< type > STRING </ type >
< value > 2.0 </ value >
< documentation >
< purpose > Version of the protocol version supported by the OAuth
server .</ purpose >
< usage > Set this variable to the OAuth server protocol version when
you are not accessing one of the built - in supported OAuth
servers .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $oauth_version = '2.0' ;
/*
{ metadocument }
< variable >
< name > url_parameters </ name >
< type > BOOLEAN </ type >
< value > 0 </ value >
< documentation >
< purpose > Determine if the API call parameters should be moved to the
call URL .</ purpose >
< usage > Set this variable to < booleanvalue > 1 </ booleanvalue > if the
API you need to call requires that the call parameters always be
passed via the API URL .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $url_parameters = false ;
/*
{ metadocument }
< variable >
< name > authorization_header </ name >
< type > BOOLEAN </ type >
< value > 1 </ value >
< documentation >
< purpose > Determine if the OAuth parameters should be passed via HTTP
Authorization request header .</ purpose >
< usage > Set this variable to < booleanvalue > 1 </ booleanvalue > if the
OAuth server requires that the OAuth parameters be passed using
the HTTP Authorization instead of the request URI parameters .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $authorization_header = true ;
/*
{ metadocument }
< variable >
< name > token_request_method </ name >
< type > STRING </ type >
< value > GET </ value >
< documentation >
< purpose > Define the HTTP method that should be used to request
tokens from the server .</ purpose >
< usage > Set this variable to < stringvalue > POST </ stringvalue > if the
OAuth server does not support requesting tokens using the HTTP GET
method .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $token_request_method = 'GET' ;
/*
{ metadocument }
< variable >
< name > signature_method </ name >
< type > STRING </ type >
< value > HMAC - SHA1 </ value >
< documentation >
< purpose > Define the method to generate the signature for API request
parameters values .</ purpose >
< usage > Currently it supports < stringvalue > PLAINTEXT </ stringvalue >
and < stringvalue > HMAC - SHA1 </ stringvalue >.</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $signature_method = 'HMAC-SHA1' ;
/*
{ metadocument }
< variable >
< name > redirect_uri </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > URL of the current script page that is calling this
class </ purpose >
< usage > Set this variable to the current script page URL before
proceeding the the OAuth authorization process .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $redirect_uri = '' ;
/*
{ metadocument }
< variable >
< name > client_id </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Identifier of your application registered with the OAuth
server </ purpose >
< usage > Set this variable to the application identifier that is
provided by the OAuth server when you register the
application .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $client_id = '' ;
/*
{ metadocument }
< variable >
< name > client_secret </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Secret value assigned to your application when it is
registered with the OAuth server .</ purpose >
< usage > Set this variable to the application secret that is provided
by the OAuth server when you register the application .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $client_secret = '' ;
/*
{ metadocument }
< variable >
< name > scope </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Permissions that your application needs to call the OAuth
server APIs </ purpose >
< usage > Check the documentation of the APIs that your application
needs to call to set this variable with the identifiers of the
permissions that the user n eeds to grant to your application .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $scope = '' ;
/*
{ metadocument }
< variable >
< name > offline </ name >
< type > BOOLEAN </ type >
< value > 0 </ value >
< documentation >
< purpose > Specify whether it will be necessary to call the API when
the user is not present and the server supports renewing expired
access tokens using refresh tokens .</ purpose >
< usage > Set this variable to < booleanvalue > 1 </ booleanvalue > if the
server supports renewing expired tokens automatically when the
user is not present .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $offline = false ;
/*
{ metadocument }
< variable >
< name > access_token </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Access token obtained from the OAuth server </ purpose >
< usage > Check this variable to get the obtained access token upon
successful OAuth authorization .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $access_token = '' ;
/*
{ metadocument }
< variable >
< name > access_token_secret </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Access token secret obtained from the OAuth server </ purpose >
< usage > If the OAuth protocol version is 1.0 or 1.0 a , check this
variable to get the obtained access token secret upon successful
OAuth authorization .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $access_token_secret = '' ;
/*
{ metadocument }
< variable >
< name > access_token_expiry </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Timestamp of the expiry of the access token obtained from
the OAuth server .</ purpose >
< usage > Check this variable to get the obtained access token expiry
time upon successful OAuth authorization . If this variable is
empty , that means no expiry time was set .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $access_token_expiry = '' ;
/*
{ metadocument }
< variable >
< name > access_token_type </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Type of access token obtained from the OAuth server .</ purpose >
< usage > Check this variable to get the obtained access token type
upon successful OAuth authorization .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $access_token_type = '' ;
/*
{ metadocument }
< variable >
< name > refresh_token </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Refresh token obtained from the OAuth server </ purpose >
< usage > Check this variable to get the obtained refresh token upon
successful OAuth authorization .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $refresh_token = '' ;
/*
{ metadocument }
< variable >
< name > access_token_error </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Error message returned when a call to the API fails .</ purpose >
< usage > Check this variable to determine if there was an error while
calling the Web services API when using the
< functionlink > CallAPI </ functionlink > function .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $access_token_error = '' ;
/*
{ metadocument }
< variable >
< name > authorization_error </ name >
< type > STRING </ type >
< value ></ value >
< documentation >
< purpose > Error message returned when it was not possible to obtain
an OAuth access token </ purpose >
< usage > Check this variable to determine if there was an error while
trying to obtain the OAuth access token .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $authorization_error = '' ;
/*
{ metadocument }
< variable >
< name > response_status </ name >
< type > INTEGER </ type >
< value > 0 </ value >
< documentation >
< purpose > HTTP response status returned by the server when calling an
API </ purpose >
< usage > Check this variable after calling the
< functionlink > CallAPI </ functionlink > function if the API calls and you
need to process the error depending the response status .
< integervalue > 200 </ integervalue > means no error .
< integervalue > 0 </ integervalue > means the server response was not
retrieved .</ usage >
</ documentation >
</ variable >
{ / metadocument }
*/
var $response_status = 0 ;
var $oauth_user_agent = 'PHP-OAuth-API (http://www.phpclasses.org/oauth-api $Revision: 1.58 $)' ;
var $session_started = false ;
Function SetError ( $error )
{
$this -> error = $error ;
if ( $this -> debug )
$this -> OutputDebug ( 'Error: ' . $error );
return ( false );
}
Function SetPHPError ( $error , & $php_error_message )
{
if ( IsSet ( $php_error_message )
&& strlen ( $php_error_message ))
$error .= " : " . $php_error_message ;
return ( $this -> SetError ( $error ));
}
Function OutputDebug ( $message )
{
if ( $this -> debug )
{
$message = $this -> debug_prefix . $message ;
$this -> debug_output .= $message . " \n " ;;
error_log ( $message );
}
return ( true );
}
Function GetRequestTokenURL ( & $request_token_url )
{
$request_token_url = $this -> request_token_url ;
return ( true );
}
Function GetDialogURL ( & $url , $redirect_uri = '' , $state = '' )
{
$url = (( $this -> offline && strlen ( $this -> offline_dialog_url )) ? $this -> offline_dialog_url : $this -> dialog_url );
if ( strlen ( $url ) === 0 )
return $this -> SetError ( 'the dialog URL ' . ( $this -> offline ? 'for offline access ' : '' ) . 'is not defined for this server' );
$url = str_replace (
'{REDIRECT_URI}' , UrlEncode ( $redirect_uri ), str_replace (
'{STATE}' , UrlEncode ( $state ), str_replace (
'{CLIENT_ID}' , UrlEncode ( $this -> client_id ), str_replace (
'{SCOPE}' , UrlEncode ( $this -> scope ),
$url ))));
return ( true );
}
Function GetAccessTokenURL ( & $access_token_url )
{
$access_token_url = $this -> access_token_url ;
return ( true );
}
Function GetStoredState ( & $state )
{
if ( ! $this -> session_started )
{
if ( ! function_exists ( 'session_start' ))
return $this -> SetError ( 'Session variables are not accessible in this PHP environment' );
}
if ( IsSet ( $_SESSION [ 'OAUTH_STATE' ]))
$state = $_SESSION [ 'OAUTH_STATE' ];
else
$state = $_SESSION [ 'OAUTH_STATE' ] = time () . '-' . substr ( md5 ( rand () . time ()), 0 , 6 );
return ( true );
}
Function GetRequestState ( & $state )
{
$check = ( strlen ( $this -> append_state_to_redirect_uri ) ? $this -> append_state_to_redirect_uri : 'state' );
$state = ( IsSet ( $_GET [ $check ]) ? $_GET [ $check ] : null );
return ( true );
}
Function GetRequestCode ( & $code )
{
$code = ( IsSet ( $_GET [ 'code' ]) ? $_GET [ 'code' ] : null );
return ( true );
}
Function GetRequestError ( & $error )
{
$error = ( IsSet ( $_GET [ 'error' ]) ? $_GET [ 'error' ] : null );
return ( true );
}
Function GetRequestDenied ( & $denied )
{
$denied = ( IsSet ( $_GET [ 'denied' ]) ? $_GET [ 'denied' ] : null );
return ( true );
}
Function GetRequestToken ( & $token , & $verifier )
{
$token = ( IsSet ( $_GET [ 'oauth_token' ]) ? $_GET [ 'oauth_token' ] : null );
$verifier = ( IsSet ( $_GET [ 'oauth_verifier' ]) ? $_GET [ 'oauth_verifier' ] : null );
return ( true );
}
Function GetRedirectURI ( & $redirect_uri )
{
if ( strlen ( $this -> redirect_uri ))
$redirect_uri = $this -> redirect_uri ;
else
$redirect_uri = 'http://' . $_SERVER [ 'HTTP_HOST' ] . $_SERVER [ 'REQUEST_URI' ];
return true ;
}
/*
{ metadocument }
< function >
< name > StoreAccessToken </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Store the values of the access token when it is succefully
retrieved from the OAuth server .</ purpose >
< usage > This function is meant to be only be called from inside the
class . By default it stores access tokens in a session variable
named < stringvalue > OAUTH_ACCESS_TOKEN </ stringvalue >.< paragraphbreak />
Actual implementations should create a sub - class and override this
function to make the access token values be stored in other types
of containers , like for instance databases .</ usage >
< returnvalue > This function should return
< booleanvalue > 1 </ booleanvalue > if the access token was stored
successfully .</ returnvalue >
</ documentation >
< argument >
< name > access_token </ name >
< type > HASH </ type >
< documentation >
< purpose > Associative array with properties of the access token .
The array may have set the following
properties :< paragraphbreak />
< stringvalue > value </ stringvalue >: string value of the access
token < paragraphbreak />
< stringvalue > authorized </ stringvalue >: boolean value that
determines if the access token was obtained
successfully < paragraphbreak />
< stringvalue > expiry </ stringvalue >: ( optional ) timestamp in ISO
format relative to UTC time zone of the access token expiry
time < paragraphbreak />
< stringvalue > type </ stringvalue >: ( optional ) type of OAuth token
that may determine how it should be used when sending API call
requests .< paragraphbreak />
< stringvalue > refresh </ stringvalue >: ( optional ) token that some
servers may set to allowing refreshing access tokens when they
expire .</ purpose >
</ documentation >
</ argument >
< do >
{ / metadocument }
*/
Function StoreAccessToken ( $access_token )
{
if ( ! $this -> session_started )
{
if ( ! function_exists ( 'session_start' ))
return $this -> SetError ( 'Session variables are not accessible in this PHP environment' );
}
$_SESSION [ 'OAUTH_ACCESS_TOKEN' ][ $this -> access_token_url ] = $access_token ;
return true ;
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
/*
{ metadocument }
< function >
< name > GetAccessToken </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Retrieve the OAuth access token if it was already
previously stored by the
< functionlink > StoreAccessToken </ functionlink > function .</ purpose >
< usage > This function is meant to be only be called from inside the
class . By default it retrieves access tokens stored in a session
variable named
< stringvalue > OAUTH_ACCESS_TOKEN </ stringvalue >.< paragraphbreak />
Actual implementations should create a sub - class and override this
function to retrieve the access token values from other types of
containers , like for instance databases .</ usage >
< returnvalue > This function should return
< booleanvalue > 1 </ booleanvalue > if the access token was retrieved
successfully .</ returnvalue >
</ documentation >
< argument >
< name > access_token </ name >
< type > STRING </ type >
< out />
< documentation >
< purpose > Return the properties of the access token in an
associative array . If the access token was not yet stored , it
returns an empty array . Otherwise , the properties it may return
are the same that may be passed to the
< functionlink > StoreAccessToken </ functionlink >.</ purpose >
</ documentation >
</ argument >
< do >
{ / metadocument }
*/
Function GetAccessToken ( & $access_token )
{
if ( ! $this -> session_started )
{
if ( ! function_exists ( 'session_start' ))
return $this -> SetError ( 'Session variables are not accessible in this PHP environment' );
if ( ! session_start ())
return ( $this -> SetPHPError ( 'it was not possible to start the PHP session' , $php_error_message ));
$this -> session_started = true ;
}
if ( IsSet ( $_SESSION [ 'OAUTH_ACCESS_TOKEN' ][ $this -> access_token_url ]))
$access_token = $_SESSION [ 'OAUTH_ACCESS_TOKEN' ][ $this -> access_token_url ];
else
$access_token = array ();
return true ;
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
/*
{ metadocument }
< function >
< name > ResetAccessToken </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Reset the access token to a state back when the user has
not yet authorized the access to the OAuth server API .</ purpose >
< usage > Call this function if for some reason the token to access
the API was revoked and you need to ask the user to authorize
the access again .< paragraphbreak />
By default the class stores and retrieves access tokens in a
session variable named
< stringvalue > OAUTH_ACCESS_TOKEN </ stringvalue >.< paragraphbreak />
This function must be called when the user is accessing your site
pages , so it can reset the information stored in session variables
that cache the state of a previously retrieved access
token .< paragraphbreak />
Actual implementations should create a sub - class and override this
function to reset the access token state when it is stored in
other types of containers , like for instance databases .</ usage >
< returnvalue > This function should return
< booleanvalue > 1 </ booleanvalue > if the access token was resetted
successfully .</ returnvalue >
</ documentation >
< do >
{ / metadocument }
*/
Function ResetAccessToken ()
{
if ( $this -> debug )
$this -> OutputDebug ( 'Resetting the access token status for OAuth server located at ' . $this -> access_token_url );
if ( ! $this -> session_started )
{
if ( ! function_exists ( 'session_start' ))
return $this -> SetError ( 'Session variables are not accessible in this PHP environment' );
if ( ! session_start ())
return ( $this -> SetPHPError ( 'it was not possible to start the PHP session' , $php_error_message ));
}
$this -> session_started = true ;
if ( IsSet ( $_SESSION [ 'OAUTH_ACCESS_TOKEN' ][ $this -> access_token_url ]))
Unset ( $_SESSION [ 'OAUTH_ACCESS_TOKEN' ][ $this -> access_token_url ]);
return true ;
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
Function Encode ( $value )
{
return ( is_array ( $value ) ? $this -> EncodeArray ( $value ) : str_replace ( '%7E' , '~' , str_replace ( '+' , ' ' , RawURLEncode ( $value ))));
}
Function EncodeArray ( $array )
{
foreach ( $array as $key => $value )
$array [ $key ] = $this -> Encode ( $value );
return $array ;
}
Function HMAC ( $function , $data , $key )
{
switch ( $function )
{
case 'sha1' :
$pack = 'H40' ;
break ;
default :
if ( $this -> debug )
$this -> OutputDebug ( $function . ' is not a supported an HMAC hash type' );
return ( '' );
}
if ( strlen ( $key ) > 64 )
$key = pack ( $pack , $function ( $key ));
if ( strlen ( $key ) < 64 )
$key = str_pad ( $key , 64 , " \0 " );
return ( pack ( $pack , $function (( str_repeat ( " \x5c " , 64 ) ^ $key ) . pack ( $pack , $function (( str_repeat ( " \x36 " , 64 ) ^ $key ) . $data )))));
}
Function SendAPIRequest ( $url , $method , $parameters , $oauth , $options , & $response )
{
$this -> response_status = 0 ;
$http = new http_class ;
$http -> debug = ( $this -> debug && $this -> debug_http );
2015-11-02 23:42:04 +00:00
$http -> timeout = 30 ;
$http -> data_timeout = 60 ;
2013-05-09 09:11:17 +00:00
$http -> log_debug = true ;
$http -> sasl_authenticate = 0 ;
$http -> user_agent = $this -> oauth_user_agent ;
$http -> redirection_limit = ( IsSet ( $options [ 'FollowRedirection' ]) ? intval ( $options [ 'FollowRedirection' ]) : 0 );
$http -> follow_redirect = ( $http -> redirection_limit != 0 );
if ( $this -> debug )
$this -> OutputDebug ( 'Accessing the ' . $options [ 'Resource' ] . ' at ' . $url );
$post_files = array ();
$method = strtoupper ( $method );
$authorization = '' ;
$type = ( IsSet ( $options [ 'RequestContentType' ]) ? strtolower ( trim ( strtok ( $options [ 'RequestContentType' ], ';' ))) : 'application/x-www-form-urlencoded' );
if ( IsSet ( $oauth ))
{
$values = array (
'oauth_consumer_key' => $this -> client_id ,
2013-07-15 04:56:23 +00:00
//'oauth_nonce'=>md5(uniqid(rand(), true)),
'oauth_nonce' => sha1 ( uniqid ( mt_rand (), true ) . uniqid ( mt_rand (), true )),
2013-05-09 09:11:17 +00:00
'oauth_signature_method' => $this -> signature_method ,
'oauth_timestamp' => time (),
'oauth_version' => '1.0' ,
);
$files = ( IsSet ( $options [ 'Files' ]) ? $options [ 'Files' ] : array ());
if ( count ( $files ))
{
foreach ( $files as $name => $value )
{
if ( ! IsSet ( $parameters [ $name ]))
return ( $this -> SetError ( 'it was specified an file parameters named ' . $name ));
$file = array ();
switch ( IsSet ( $value [ 'Type' ]) ? $value [ 'Type' ] : 'FileName' )
{
case 'FileName' :
$file [ 'FileName' ] = $parameters [ $name ];
break ;
case 'Data' :
$file [ 'Data' ] = $parameters [ $name ];
break ;
default :
return ( $this -> SetError ( $value [ 'Type' ] . ' is not a valid type for file ' . $name ));
}
$file [ 'ContentType' ] = ( IsSet ( $value [ 'Content-Type' ]) ? $value [ 'Content-Type' ] : 'automatic/name' );
$post_files [ $name ] = $file ;
}
UnSet ( $parameters [ $name ]);
if ( $method !== 'POST' )
{
$this -> OutputDebug ( 'For uploading files the method should be POST not ' . $method );
$method = 'POST' ;
}
if ( $type !== 'multipart/form-data' )
{
if ( IsSet ( $options [ 'RequestContentType' ]))
return ( $this -> SetError ( 'the request content type for uploading files should be multipart/form-data' ));
$type = 'multipart/form-data' ;
}
$value_parameters = array ();
}
else
{
if ( $this -> url_parameters
&& $type === 'application/x-www-form-urlencoded'
&& count ( $parameters ))
{
$first = ( strpos ( $url , '?' ) === false );
foreach ( $parameters as $parameter => $value )
{
$url .= ( $first ? '?' : '&' ) . UrlEncode ( $parameter ) . '=' . UrlEncode ( $value );
$first = false ;
}
$parameters = array ();
}
$value_parameters = ( $type !== 'application/x-www-form-urlencoded' ? array () : $parameters );
}
$values = array_merge ( $values , $oauth , $value_parameters );
$key = $this -> Encode ( $this -> client_secret ) . '&' . $this -> Encode ( $this -> access_token_secret );
switch ( $this -> signature_method )
{
case 'PLAINTEXT' :
$values [ 'oauth_signature' ] = $key ;
break ;
case 'HMAC-SHA1' :
$uri = strtok ( $url , '?' );
$sign = $method . '&' . $this -> Encode ( $uri ) . '&' ;
$first = true ;
$sign_values = $values ;
$u = parse_url ( $url );
if ( IsSet ( $u [ 'query' ]))
{
parse_str ( $u [ 'query' ], $q );
foreach ( $q as $parameter => $value )
$sign_values [ $parameter ] = $value ;
}
KSort ( $sign_values );
foreach ( $sign_values as $parameter => $value )
{
$sign .= $this -> Encode (( $first ? '' : '&' ) . $parameter . '=' . $this -> Encode ( $value ));
$first = false ;
}
$values [ 'oauth_signature' ] = base64_encode ( $this -> HMAC ( 'sha1' , $sign , $key ));
break ;
default :
return $this -> SetError ( $this -> signature_method . ' signature method is not yet supported' );
}
if ( $this -> authorization_header )
{
$authorization = 'OAuth' ;
$first = true ;
foreach ( $values as $parameter => $value )
{
$authorization .= ( $first ? ' ' : ',' ) . $parameter . '="' . $this -> Encode ( $value ) . '"' ;
$first = false ;
}
}
else
{
if ( $method === 'GET'
|| ( IsSet ( $options [ 'PostValuesInURI' ])
&& $options [ 'PostValuesInURI' ]))
{
$first = ( strcspn ( $url , '?' ) == strlen ( $url ));
foreach ( $values as $parameter => $value )
{
$url .= ( $first ? '?' : '&' ) . $parameter . '=' . $this -> Encode ( $value );
$first = false ;
}
$post_values = array ();
}
else
$post_values = $values ;
}
}
if ( strlen ( $error = $http -> GetRequestArguments ( $url , $arguments )))
return ( $this -> SetError ( 'it was not possible to open the ' . $options [ 'Resource' ] . ' URL: ' . $error ));
if ( strlen ( $error = $http -> Open ( $arguments )))
return ( $this -> SetError ( 'it was not possible to open the ' . $options [ 'Resource' ] . ' URL: ' . $error ));
if ( count ( $post_files ))
$arguments [ 'PostFiles' ] = $post_files ;
$arguments [ 'RequestMethod' ] = $method ;
switch ( $type )
{
case 'application/x-www-form-urlencoded' :
case 'multipart/form-data' :
if ( IsSet ( $options [ 'RequestBody' ]))
return ( $this -> SetError ( 'the request body is defined automatically from the parameters' ));
$arguments [ 'PostValues' ] = $parameters ;
break ;
case 'application/json' :
$arguments [ 'Headers' ][ 'Content-Type' ] = $options [ 'RequestContentType' ];
if ( ! IsSet ( $options [ 'RequestBody' ]))
{
$arguments [ 'Body' ] = json_encode ( $parameters );
break ;
}
default :
if ( ! IsSet ( $options [ 'RequestBody' ]))
return ( $this -> SetError ( 'it was not specified the body value of the of the API call request' ));
$arguments [ 'Headers' ][ 'Content-Type' ] = $options [ 'RequestContentType' ];
$arguments [ 'Body' ] = $options [ 'RequestBody' ];
break ;
}
$arguments [ 'Headers' ][ 'Accept' ] = ( IsSet ( $options [ 'Accept' ]) ? $options [ 'Accept' ] : '*/*' );
if ( strlen ( $authorization ))
$arguments [ 'Headers' ][ 'Authorization' ] = $authorization ;
if ( strlen ( $error = $http -> SendRequest ( $arguments ))
|| strlen ( $error = $http -> ReadReplyHeaders ( $headers )))
{
$http -> Close ();
return ( $this -> SetError ( 'it was not possible to retrieve the ' . $options [ 'Resource' ] . ': ' . $error ));
}
$error = $http -> ReadWholeReplyBody ( $data );
$http -> Close ();
if ( strlen ( $error ))
{
return ( $this -> SetError ( 'it was not possible to access the ' . $options [ 'Resource' ] . ': ' . $error ));
}
$this -> response_status = intval ( $http -> response_status );
$content_type = ( IsSet ( $options [ 'ResponseContentType' ]) ? $options [ 'ResponseContentType' ] : ( IsSet ( $headers [ 'content-type' ]) ? strtolower ( trim ( strtok ( $headers [ 'content-type' ], ';' ))) : 'unspecified' ));
switch ( $content_type )
{
case 'text/javascript' :
case 'application/json' :
if ( ! function_exists ( 'json_decode' ))
return ( $this -> SetError ( 'the JSON extension is not available in this PHP setup' ));
$object = json_decode ( $data );
switch ( GetType ( $object ))
{
case 'object' :
if ( ! IsSet ( $options [ 'ConvertObjects' ])
|| ! $options [ 'ConvertObjects' ])
$response = $object ;
else
{
$response = array ();
foreach ( $object as $property => $value )
$response [ $property ] = $value ;
}
break ;
case 'array' :
$response = $object ;
break ;
default :
if ( ! IsSet ( $object ))
return ( $this -> SetError ( 'it was not returned a valid JSON definition of the ' . $options [ 'Resource' ] . ' values' ));
$response = $object ;
break ;
}
break ;
case 'application/x-www-form-urlencoded' :
case 'text/plain' :
case 'text/html' :
parse_str ( $data , $response );
break ;
default :
$response = $data ;
break ;
}
if ( $this -> response_status >= 200
&& $this -> response_status < 300 )
$this -> access_token_error = '' ;
else
{
$this -> access_token_error = 'it was not possible to access the ' . $options [ 'Resource' ] . ': it was returned an unexpected response status ' . $http -> response_status . ' Response: ' . $data ;
if ( $this -> debug )
$this -> OutputDebug ( 'Could not retrieve the OAuth access. Error: ' . $this -> access_token_error );
if ( IsSet ( $options [ 'FailOnAccessError' ])
&& $options [ 'FailOnAccessError' ])
{
$this -> error = $this -> access_token_error ;
return false ;
}
}
return true ;
}
Function ProcessToken ( $code , $refresh )
{
if ( $refresh )
{
$values = array (
'client_id' => $this -> client_id ,
'client_secret' => $this -> client_secret ,
'refresh_token' => $this -> refresh_token ,
'grant_type' => 'refresh_token'
);
}
else
{
if ( ! $this -> GetRedirectURI ( $redirect_uri ))
return false ;
$values = array (
'code' => $code ,
'client_id' => $this -> client_id ,
'client_secret' => $this -> client_secret ,
'redirect_uri' => $redirect_uri ,
'grant_type' => 'authorization_code'
);
}
if ( ! $this -> GetAccessTokenURL ( $url ))
return false ;
if ( ! $this -> SendAPIRequest ( $url , 'POST' , $values , null , array ( 'Resource' => 'OAuth ' . ( $refresh ? 'refresh' : 'access' ) . ' token' , 'ConvertObjects' => true ), $response ))
return false ;
if ( strlen ( $this -> access_token_error ))
{
$this -> authorization_error = $this -> access_token_error ;
return true ;
}
if ( ! IsSet ( $response [ 'access_token' ]))
{
if ( IsSet ( $response [ 'error' ]))
{
$this -> authorization_error = 'it was not possible to retrieve the access token: it was returned the error: ' . $response [ 'error' ];
return true ;
}
return ( $this -> SetError ( 'OAuth server did not return the access token' ));
}
$access_token = array (
'value' => $this -> access_token = $response [ 'access_token' ],
'authorized' => true
);
if ( $this -> debug )
$this -> OutputDebug ( 'Access token: ' . $this -> access_token );
if ( IsSet ( $response [ 'expires' ])
|| IsSet ( $response [ 'expires_in' ]))
{
$expires = ( IsSet ( $response [ 'expires' ]) ? $response [ 'expires' ] : $response [ 'expires_in' ]);
if ( strval ( $expires ) !== strval ( intval ( $expires ))
|| $expires <= 0 )
return ( $this -> SetError ( 'OAuth server did not return a supported type of access token expiry time' ));
$this -> access_token_expiry = gmstrftime ( '%Y-%m-%d %H:%M:%S' , time () + $expires );
if ( $this -> debug )
$this -> OutputDebug ( 'Access token expiry: ' . $this -> access_token_expiry . ' UTC' );
$access_token [ 'expiry' ] = $this -> access_token_expiry ;
}
else
$this -> access_token_expiry = '' ;
if ( IsSet ( $response [ 'token_type' ]))
{
$this -> access_token_type = $response [ 'token_type' ];
if ( $this -> debug )
$this -> OutputDebug ( 'Access token type: ' . $this -> access_token_type );
$access_token [ 'type' ] = $this -> access_token_type ;
}
else
$this -> access_token_type = '' ;
if ( $refresh )
$response [ 'refresh_token' ] = $this -> refresh_token ;
elseif ( IsSet ( $response [ 'refresh_token' ]))
{
$this -> refresh_token = $response [ 'refresh_token' ];
if ( $this -> debug )
$this -> OutputDebug ( 'Refresh token: ' . $this -> refresh_token );
$access_token [ 'refresh' ] = $this -> refresh_token ;
}
else
$this -> refresh_token = '' ;
if ( ! $this -> StoreAccessToken ( $access_token ))
return false ;
return true ;
}
Function RetrieveToken ( & $valid )
{
$valid = false ;
if ( ! $this -> GetAccessToken ( $access_token ))
return false ;
if ( IsSet ( $access_token [ 'value' ]))
{
$this -> access_token_expiry = '' ;
if ( IsSet ( $access_token [ 'expiry' ])
&& strcmp ( $this -> access_token_expiry = $access_token [ 'expiry' ], gmstrftime ( '%Y-%m-%d %H:%M:%S' )) < 0 )
{
$this -> access_token = '' ;
if ( $this -> debug )
$this -> OutputDebug ( 'The OAuth access token expired in ' . $this -> access_token_expiry );
}
else
{
$this -> access_token = $access_token [ 'value' ];
if ( IsSet ( $access_token [ 'type' ]))
$this -> access_token_type = $access_token [ 'type' ];
else
$this -> access_token_type = '' ;
if ( $this -> debug )
$this -> OutputDebug ( 'The OAuth access token ' . $this -> access_token . ' is valid' );
if ( strlen ( $this -> access_token_type )
&& $this -> debug )
$this -> OutputDebug ( 'The OAuth access token is of type ' . $this -> access_token_type );
if ( IsSet ( $access_token [ 'refresh' ]))
$this -> refresh_token = $access_token [ 'refresh' ];
else
$this -> refresh_token = '' ;
$valid = true ;
}
}
return true ;
}
/*
{ metadocument }
< function >
< name > CallAPI </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Send a HTTP request to the Web services API using a
previously obtained authorization token via OAuth .</ purpose >
< usage > This function can be used to call an API after having
previously obtained an access token through the OAuth protocol
using the < functionlink > Process </ functionlink > function , or by
directly setting the variables
< variablelink > access_token </ variablelink > , as well as
< variablelink > access_token_secret </ variablelink > in case of using
OAuth 1.0 or 1.0 a services .</ usage >
< returnvalue > This function returns < booleanvalue > 1 </ booleanvalue > if
the call was done successfully .</ returnvalue >
</ documentation >
< argument >
< name > url </ name >
< type > STRING </ type >
< documentation >
< purpose > URL of the API where the HTTP request will be sent .</ purpose >
</ documentation >
</ argument >
< argument >
< name > method </ name >
< type > STRING </ type >
< documentation >
< purpose > HTTP method that will be used to send the request . It can
be < stringvalue > GET </ stringvalue > ,
< stringvalue > POST </ stringvalue > ,
< stringvalue > DELETE </ stringvalue > , < stringvalue > PUT </ stringvalue > ,
etc ..</ purpose >
</ documentation >
</ argument >
< argument >
< name > parameters </ name >
< type > HASH </ type >
< documentation >
< purpose > Associative array with the names and values of the API
call request parameters .</ purpose >
</ documentation >
</ argument >
< argument >
< name > options </ name >
< type > HASH </ type >
< documentation >
< purpose > Associative array with additional options to configure
the request . Currently it supports the following
options :< paragraphbreak />
< stringvalue > 2 Legged </ stringvalue >: boolean option that
determines if the API request should be 2 legged . The default
value is < tt >< booleanvalue > 0 </ booleanvalue ></ tt >.< paragraphbreak />
< stringvalue > Accept </ stringvalue >: content type value of the
Accept HTTP header to be sent in the API call HTTP request .
Some APIs require that a certain value be sent to specify
which version of the API is being called . The default value is
< stringvalue >*& #47;*</stringvalue>.<paragraphbreak />
< stringvalue > ConvertObjects </ stringvalue >: boolean option that
determines if objects should be converted into arrays when the
response is returned in JSON format . The default value is
< booleanvalue > 0 </ booleanvalue >.< paragraphbreak />
< stringvalue > FailOnAccessError </ stringvalue >: boolean option
that determines if this functions should fail when the server
response status is not between 200 and 299. The default value
is < booleanvalue > 0 </ booleanvalue >.< paragraphbreak />
< stringvalue > Files </ stringvalue >: associative array with
details of the parameters that must be passed as file uploads .
The array indexes must have the same name of the parameters
to be sent as files . The respective array entry values must
also be associative arrays with the parameters for each file .
Currently it supports the following parameters :< paragraphbreak />
- < tt > Type </ tt > - defines how the parameter value should be
treated . It can be < tt > 'FileName' </ tt > if the parameter value is
is the name of a local file to be uploaded . It may also be
< tt > 'Data' </ tt > if the parameter value is the actual data of
the file to be uploaded .< paragraphbreak />
- Default : < tt > 'FileName' </ tt >< paragraphbreak />
- < tt > ContentType </ tt > - MIME value of the content type of the
file . It can be < tt > 'automatic/name' </ tt > if the content type
should be determine from the file name extension .< paragraphbreak />
- Default : < tt > 'automatic/name' </ tt >< paragraphbreak />
< stringvalue > PostValuesInURI </ stringvalue >: boolean option to
determine that a POST request should pass the request values
in the URI . The default value is
< booleanvalue > 0 </ booleanvalue >.< paragraphbreak />
< stringvalue > FollowRedirection </ stringvalue >: limit number of
times that HTTP response redirects will be followed . If it is
set to < integervalue > 0 </ integervalue > , redirection responses
fail in error . The default value is
< integervalue > 0 </ integervalue >.< paragraphbreak />
< stringvalue > RequestBody </ stringvalue >: request body data of a
custom type . The < stringvalue > RequestContentType </ stringvalue >
option must be specified , so the
< stringvalue > RequestBody </ stringvalue > option is considered .< paragraphbreak />
< stringvalue > RequestContentType </ stringvalue >: content type that
should be used to send the request values . It can be either
< stringvalue > application / x - www - form - urlencoded </ stringvalue >
for sending values like from Web forms , or
< stringvalue > application / json </ stringvalue > for sending the
values encoded in JSON format . Other types are accepted if the
< stringvalue > RequestBody </ stringvalue > option is specified .
The default value is
< stringvalue > application / x - www - form - urlencoded </ stringvalue >.< paragraphbreak />
< stringvalue > RequestBody </ stringvalue >: request body data of a
custom type . The < stringvalue > RequestContentType </ stringvalue >
option must be specified , so the
< stringvalue > RequestBody </ stringvalue > option is considered .< paragraphbreak />
< stringvalue > Resource </ stringvalue >: string with a label that
will be used in the error messages and debug log entries to
identify what operation the request is performing . The default
value is < stringvalue > API call </ stringvalue >.< paragraphbreak />
< stringvalue > ResponseContentType </ stringvalue >: content type
that should be considered when decoding the API request
response . This overrides the < tt > Content - Type </ tt > header
returned by the server . If the content type is
< stringvalue > application / x - www - form - urlencoded </ stringvalue >
the function will parse the data returning an array of
key - value pairs . If the content type is
< stringvalue > application / json </ stringvalue > the response will
be decode as a JSON - encoded data type . Other content type
values will make the function return the original response
value as it was returned from the server . The default value
for this option is to use what the server returned in the
< tt > Content - Type </ tt > header .</ purpose >
</ documentation >
</ argument >
< argument >
< name > response </ name >
< type > STRING </ type >
< out />
< documentation >
< purpose > Return the value of the API response . If the value is
JSON encoded , this function will decode it and return the value
converted to respective types . If the value is form encoded ,
this function will decode the response and return it as an
array . Otherwise , the class will return the value as a
string .</ purpose >
</ documentation >
</ argument >
< do >
{ / metadocument }
*/
Function CallAPI ( $url , $method , $parameters , $options , & $response )
{
if ( ! IsSet ( $options [ 'Resource' ]))
$options [ 'Resource' ] = 'API call' ;
if ( ! IsSet ( $options [ 'ConvertObjects' ]))
$options [ 'ConvertObjects' ] = false ;
if ( strlen ( $this -> access_token ) === 0 )
{
if ( ! $this -> RetrieveToken ( $valid ))
return false ;
if ( ! $valid )
return $this -> SetError ( 'the access token is not set to a valid value' );
}
switch ( intval ( $this -> oauth_version ))
{
case 1 :
$oauth = array (
'oauth_token' => (( IsSet ( $options [ '2Legged' ]) && $options [ '2Legged' ]) ? '' : $this -> access_token )
);
break ;
case 2 :
if ( strlen ( $this -> access_token_expiry )
&& strcmp ( $this -> access_token_expiry , gmstrftime ( '%Y-%m-%d %H:%M:%S' )) <= 0 )
{
if ( strlen ( $this -> refresh_token ) === 0 )
return ( $this -> SetError ( 'the access token expired and no refresh token is available' ));
if ( $this -> debug )
{
$this -> OutputDebug ( 'The access token expired on ' . $this -> access_token_expiry );
$this -> OutputDebug ( 'Refreshing the access token' );
}
if ( ! $this -> ProcessToken ( null , true ))
return false ;
}
$oauth = null ;
$url .= ( strcspn ( $url , '?' ) < strlen ( $url ) ? '&' : '?' ) . 'access_token=' . UrlEncode ( $this -> access_token );
break ;
default :
return ( $this -> SetError ( $this -> oauth_version . ' is not a supported version of the OAuth protocol' ));
}
return ( $this -> SendAPIRequest ( $url , $method , $parameters , $oauth , $options , $response ));
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
/*
{ metadocument }
< function >
< name > Initialize </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Initialize the class variables and internal state . It must
be called before calling other class functions .</ purpose >
< usage > Set the < variablelink > server </ variablelink > variable before
calling this function to let it initialize the class variables to
work with the specified server type . Alternatively , you can set
other class variables manually to make it work with servers that
are not yet built - in supported .</ usage >
< returnvalue > This function returns < booleanvalue > 1 </ booleanvalue > if
it was able to successfully initialize the class for the specified
server type .</ returnvalue >
</ documentation >
< do >
{ / metadocument }
*/
Function Initialize ()
{
if ( strlen ( $this -> server ) === 0 )
return true ;
$this -> request_token_url = '' ;
$this -> append_state_to_redirect_uri = '' ;
$this -> authorization_header = true ;
$this -> url_parameters = false ;
$this -> token_request_method = 'GET' ;
$this -> signature_method = 'HMAC-SHA1' ;
switch ( $this -> server )
{
case 'Bitbucket' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://bitbucket.org/!api/1.0/oauth/request_token' ;
$this -> dialog_url = 'https://bitbucket.org/!api/1.0/oauth/authenticate' ;
$this -> access_token_url = 'https://bitbucket.org/!api/1.0/oauth/access_token' ;
$this -> url_parameters = true ;
break ;
case 'Box' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://www.box.com/api/oauth2/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&state={STATE}' ;
$this -> offline_dialog_url = 'https://www.box.com/api/oauth2/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&state={STATE}&access_type=offline&approval_prompt=force' ;
$this -> access_token_url = 'https://www.box.com/api/oauth2/token' ;
break ;
case 'Dropbox' :
$this -> oauth_version = '1.0' ;
$this -> request_token_url = 'https://api.dropbox.com/1/oauth/request_token' ;
$this -> dialog_url = 'https://www.dropbox.com/1/oauth/authorize' ;
$this -> access_token_url = 'https://api.dropbox.com/1/oauth/access_token' ;
$this -> authorization_header = false ;
break ;
case 'Eventful' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'http://eventful.com/oauth/request_token' ;
$this -> dialog_url = 'http://eventful.com/oauth/authorize' ;
$this -> access_token_url = 'http://eventful.com/oauth/access_token' ;
$this -> authorization_header = false ;
$this -> url_parameters = true ;
$this -> token_request_method = 'POST' ;
break ;
case 'Evernote' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://sandbox.evernote.com/oauth' ;
$this -> dialog_url = 'https://sandbox.evernote.com/OAuth.action' ;
$this -> access_token_url = 'https://sandbox.evernote.com/oauth' ;
$this -> url_parameters = true ;
$this -> authorization_header = false ;
break ;
case 'Facebook' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://www.facebook.com/dialog/oauth?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope={SCOPE}&state={STATE}' ;
$this -> access_token_url = 'https://graph.facebook.com/oauth/access_token' ;
break ;
case 'Fitbit' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'http://api.fitbit.com/oauth/request_token' ;
$this -> dialog_url = 'http://api.fitbit.com/oauth/authorize' ;
$this -> access_token_url = 'http://api.fitbit.com/oauth/access_token' ;
break ;
case 'Flickr' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'http://www.flickr.com/services/oauth/request_token' ;
$this -> dialog_url = 'http://www.flickr.com/services/oauth/authorize?perms={SCOPE}' ;
$this -> access_token_url = 'http://www.flickr.com/services/oauth/access_token' ;
$this -> authorization_header = false ;
break ;
case 'Foursquare' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://foursquare.com/oauth2/authorize?client_id={CLIENT_ID}&scope={SCOPE}&response_type=code&redirect_uri={REDIRECT_URI}&state={STATE}' ;
$this -> access_token_url = 'https://foursquare.com/oauth2/access_token' ;
break ;
case 'github' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://github.com/login/oauth/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope={SCOPE}&state={STATE}' ;
$this -> access_token_url = 'https://github.com/login/oauth/access_token' ;
break ;
case 'Google' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope={SCOPE}&state={STATE}' ;
$this -> offline_dialog_url = 'https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope={SCOPE}&state={STATE}&access_type=offline&approval_prompt=force' ;
$this -> access_token_url = 'https://accounts.google.com/o/oauth2/token' ;
break ;
case 'Instagram' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://api.instagram.com/oauth/authorize/?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope={SCOPE}&response_type=code&state={STATE}' ;
$this -> access_token_url = 'https://api.instagram.com/oauth/access_token' ;
break ;
case 'LinkedIn' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://api.linkedin.com/uas/oauth/requestToken?scope={SCOPE}' ;
$this -> dialog_url = 'https://api.linkedin.com/uas/oauth/authenticate' ;
$this -> access_token_url = 'https://api.linkedin.com/uas/oauth/accessToken' ;
$this -> url_parameters = true ;
break ;
case 'Microsoft' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://login.live.com/oauth20_authorize.srf?client_id={CLIENT_ID}&scope={SCOPE}&response_type=code&redirect_uri={REDIRECT_URI}&state={STATE}' ;
$this -> access_token_url = 'https://login.live.com/oauth20_token.srf' ;
break ;
case 'RightSignature' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://rightsignature.com/oauth/request_token' ;
$this -> dialog_url = 'https://rightsignature.com/oauth/authorize' ;
$this -> access_token_url = 'https://rightsignature.com/oauth/access_token' ;
$this -> authorization_header = false ;
break ;
case 'Scoop.it' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://www.scoop.it/oauth/request' ;
$this -> dialog_url = 'https://www.scoop.it/oauth/authorize' ;
$this -> access_token_url = 'https://www.scoop.it/oauth/access' ;
$this -> authorization_header = false ;
break ;
case 'StockTwits' :
$this -> oauth_version = '2.0' ;
$this -> dialog_url = 'https://api.stocktwits.com/api/2/oauth/authorize?client_id={CLIENT_ID}&response_type=code&redirect_uri={REDIRECT_URI}&scope={SCOPE}&state={STATE}' ;
$this -> access_token_url = 'https://api.stocktwits.com/api/2/oauth/token' ;
break ;
case 'Tumblr' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'http://www.tumblr.com/oauth/request_token' ;
$this -> dialog_url = 'http://www.tumblr.com/oauth/authorize' ;
$this -> access_token_url = 'http://www.tumblr.com/oauth/access_token' ;
break ;
case 'Twitter' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://api.twitter.com/oauth/request_token' ;
$this -> dialog_url = 'https://api.twitter.com/oauth/authenticate' ;
$this -> access_token_url = 'https://api.twitter.com/oauth/access_token' ;
$this -> url_parameters = true ;
break ;
case 'XING' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://api.xing.com/v1/request_token' ;
$this -> dialog_url = 'https://api.xing.com/v1/authorize' ;
$this -> access_token_url = 'https://api.xing.com/v1/access_token' ;
$this -> authorization_header = false ;
break ;
case 'Yahoo' :
$this -> oauth_version = '1.0a' ;
$this -> request_token_url = 'https://api.login.yahoo.com/oauth/v2/get_request_token' ;
$this -> dialog_url = 'https://api.login.yahoo.com/oauth/v2/request_auth' ;
$this -> access_token_url = 'https://api.login.yahoo.com/oauth/v2/get_token' ;
$this -> authorization_header = false ;
break ;
default :
return ( $this -> SetError ( $this -> server . ' is not yet a supported type of OAuth server. Please contact the author Manuel Lemos <mlemos@acm.org> to request adding built-in support to this type of OAuth server.' ));
}
return ( true );
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
/*
{ metadocument }
< function >
< name > Process </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Process the OAuth protocol interaction with the OAuth
server .</ purpose >
< usage > Call this function when you need to retrieve the OAuth access
token . Check the < variablelink > access_token </ variablelink > to
determine if the access token was obtained successfully .</ usage >
< returnvalue > This function returns < booleanvalue > 1 </ booleanvalue > if
the OAuth protocol was processed without errors .</ returnvalue >
</ documentation >
< do >
{ / metadocument }
*/
Function Process ()
{
switch ( intval ( $this -> oauth_version ))
{
case 1 :
$one_a = ( $this -> oauth_version === '1.0a' );
if ( $this -> debug )
$this -> OutputDebug ( 'Checking the OAuth token authorization state' );
if ( ! $this -> GetAccessToken ( $access_token ))
return false ;
if ( IsSet ( $access_token [ 'authorized' ])
&& IsSet ( $access_token [ 'value' ]))
{
$expired = ( IsSet ( $access_token [ 'expiry' ]) && strcmp ( $access_token [ 'expiry' ], gmstrftime ( '%Y-%m-%d %H:%M:%S' )) <= 0 );
if ( ! $access_token [ 'authorized' ]
|| $expired )
{
if ( $this -> debug )
{
if ( $expired )
$this -> OutputDebug ( 'The OAuth token expired on ' . $access_token [ 'expiry' ] . 'UTC' );
else
$this -> OutputDebug ( 'The OAuth token is not yet authorized' );
$this -> OutputDebug ( 'Checking the OAuth token and verifier' );
}
if ( ! $this -> GetRequestToken ( $token , $verifier ))
return false ;
if ( ! IsSet ( $token )
|| ( $one_a
&& ! IsSet ( $verifier )))
{
if ( ! $this -> GetRequestDenied ( $denied ))
return false ;
if ( IsSet ( $denied )
&& $denied === $access_token [ 'value' ])
{
if ( $this -> debug )
$this -> OutputDebug ( 'The authorization request was denied' );
$this -> authorization_error = 'the request was denied' ;
return true ;
}
else
{
if ( $this -> debug )
$this -> OutputDebug ( 'Reset the OAuth token state because token and verifier are not both set' );
$access_token = array ();
}
}
elseif ( $token !== $access_token [ 'value' ])
{
if ( $this -> debug )
$this -> OutputDebug ( 'Reset the OAuth token state because token does not match what as previously retrieved' );
$access_token = array ();
}
else
{
if ( ! $this -> GetAccessTokenURL ( $url ))
return false ;
$oauth = array (
'oauth_token' => $token ,
);
if ( $one_a )
$oauth [ 'oauth_verifier' ] = $verifier ;
$this -> access_token_secret = $access_token [ 'secret' ];
$options = array ( 'Resource' => 'OAuth access token' );
$method = strtoupper ( $this -> token_request_method );
switch ( $method )
{
case 'GET' :
break ;
case 'POST' :
$options [ 'PostValuesInURI' ] = true ;
break ;
default :
$this -> error = $method . ' is not a supported method to request tokens' ;
break ;
}
if ( ! $this -> SendAPIRequest ( $url , $method , array (), $oauth , $options , $response ))
return false ;
if ( strlen ( $this -> access_token_error ))
{
$this -> authorization_error = $this -> access_token_error ;
return true ;
}
if ( ! IsSet ( $response [ 'oauth_token' ])
|| ! IsSet ( $response [ 'oauth_token_secret' ]))
{
$this -> authorization_error = 'it was not returned the access token and secret' ;
return true ;
}
$access_token = array (
'value' => $response [ 'oauth_token' ],
'secret' => $response [ 'oauth_token_secret' ],
'authorized' => true
);
if ( IsSet ( $response [ 'oauth_expires_in' ]))
{
$expires = $response [ 'oauth_expires_in' ];
if ( strval ( $expires ) !== strval ( intval ( $expires ))
|| $expires <= 0 )
return ( $this -> SetError ( 'OAuth server did not return a supported type of access token expiry time' ));
$this -> access_token_expiry = gmstrftime ( '%Y-%m-%d %H:%M:%S' , time () + $expires );
if ( $this -> debug )
$this -> OutputDebug ( 'Access token expiry: ' . $this -> access_token_expiry . ' UTC' );
$access_token [ 'expiry' ] = $this -> access_token_expiry ;
}
else
$this -> access_token_expiry = '' ;
if ( ! $this -> StoreAccessToken ( $access_token ))
return false ;
if ( $this -> debug )
$this -> OutputDebug ( 'The OAuth token was authorized' );
}
}
elseif ( $this -> debug )
$this -> OutputDebug ( 'The OAuth token was already authorized' );
if ( IsSet ( $access_token [ 'authorized' ])
&& $access_token [ 'authorized' ])
{
$this -> access_token = $access_token [ 'value' ];
$this -> access_token_secret = $access_token [ 'secret' ];
return true ;
}
}
else
{
if ( $this -> debug )
$this -> OutputDebug ( 'The OAuth access token is not set' );
$access_token = array ();
}
if ( ! IsSet ( $access_token [ 'authorized' ]))
{
if ( $this -> debug )
$this -> OutputDebug ( 'Requesting the unauthorized OAuth token' );
if ( ! $this -> GetRequestTokenURL ( $url ))
return false ;
$url = str_replace ( '{SCOPE}' , UrlEncode ( $this -> scope ), $url );
if ( ! $this -> GetRedirectURI ( $redirect_uri ))
return false ;
$oauth = array (
'oauth_callback' => $redirect_uri ,
);
$options = array ( 'Resource' => 'OAuth request token' );
$method = strtoupper ( $this -> token_request_method );
switch ( $method )
{
case 'GET' :
break ;
case 'POST' :
$options [ 'PostValuesInURI' ] = true ;
break ;
default :
$this -> error = $method . ' is not a supported method to request tokens' ;
break ;
}
if ( ! $this -> SendAPIRequest ( $url , $method , array (), $oauth , $options , $response ))
return false ;
if ( strlen ( $this -> access_token_error ))
{
$this -> authorization_error = $this -> access_token_error ;
return true ;
}
if ( ! IsSet ( $response [ 'oauth_token' ])
|| ! IsSet ( $response [ 'oauth_token_secret' ]))
{
$this -> authorization_error = 'it was not returned the requested token' ;
return true ;
}
$access_token = array (
'value' => $response [ 'oauth_token' ],
'secret' => $response [ 'oauth_token_secret' ],
'authorized' => false
);
if ( ! $this -> StoreAccessToken ( $access_token ))
return false ;
}
if ( ! $this -> GetDialogURL ( $url ))
return false ;
$url .= ( strpos ( $url , '?' ) === false ? '?' : '&' ) . 'oauth_token=' . $access_token [ 'value' ];
if ( ! $one_a )
{
if ( ! $this -> GetRedirectURI ( $redirect_uri ))
return false ;
$url .= '&oauth_callback=' . UrlEncode ( $redirect_uri );
}
if ( $this -> debug )
$this -> OutputDebug ( 'Redirecting to OAuth authorize page ' . $url );
Header ( 'HTTP/1.0 302 OAuth Redirection' );
Header ( 'Location: ' . $url );
$this -> exit = true ;
return true ;
case 2 :
if ( $this -> debug )
$this -> OutputDebug ( 'Checking if OAuth access token was already retrieved from ' . $this -> access_token_url );
if ( ! $this -> RetrieveToken ( $valid ))
return false ;
if ( $valid )
return true ;
if ( $this -> debug )
$this -> OutputDebug ( 'Checking the authentication state in URI ' . $_SERVER [ 'REQUEST_URI' ]);
if ( ! $this -> GetStoredState ( $stored_state ))
return false ;
if ( strlen ( $stored_state ) == 0 )
return ( $this -> SetError ( 'it was not set the OAuth state' ));
if ( ! $this -> GetRequestState ( $state ))
return false ;
if ( $state === $stored_state )
{
if ( $this -> debug )
$this -> OutputDebug ( 'Checking the authentication code' );
if ( ! $this -> GetRequestCode ( $code ))
return false ;
if ( strlen ( $code ) == 0 )
{
if ( ! $this -> GetRequestError ( $this -> authorization_error ))
return false ;
if ( IsSet ( $this -> authorization_error ))
{
if ( $this -> debug )
$this -> OutputDebug ( 'Authorization failed with error code ' . $this -> authorization_error );
switch ( $this -> authorization_error )
{
case 'invalid_request' :
case 'unauthorized_client' :
case 'access_denied' :
case 'unsupported_response_type' :
case 'invalid_scope' :
case 'server_error' :
case 'temporarily_unavailable' :
case 'user_denied' :
return true ;
default :
return ( $this -> SetError ( 'it was returned an unknown OAuth error code' ));
}
}
return ( $this -> SetError ( 'it was not returned the OAuth dialog code' ));
}
if ( ! $this -> ProcessToken ( $code , false ))
return false ;
}
else
{
if ( ! $this -> GetRedirectURI ( $redirect_uri ))
return false ;
if ( strlen ( $this -> append_state_to_redirect_uri ))
$redirect_uri .= ( strpos ( $redirect_uri , '?' ) === false ? '?' : '&' ) . $this -> append_state_to_redirect_uri . '=' . $stored_state ;
if ( ! $this -> GetDialogURL ( $url , $redirect_uri , $stored_state ))
return false ;
if ( strlen ( $url ) == 0 )
return ( $this -> SetError ( 'it was not set the OAuth dialog URL' ));
if ( $this -> debug )
$this -> OutputDebug ( 'Redirecting to OAuth Dialog ' . $url );
Header ( 'HTTP/1.0 302 OAuth Redirection' );
Header ( 'Location: ' . $url );
$this -> exit = true ;
}
break ;
default :
return ( $this -> SetError ( $this -> oauth_version . ' is not a supported version of the OAuth protocol' ));
}
return ( true );
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
/*
{ metadocument }
< function >
< name > Finalize </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Cleanup any resources that may have been used during the
OAuth protocol processing or execution of API calls .</ purpose >
< usage > Always call this function as the last step after calling the
functions < functionlink > Process </ functionlink > or
< functionlink > CallAPI </ functionlink >.</ usage >
< returnvalue > This function returns < booleanvalue > 1 </ booleanvalue > if
the function cleaned up any resources successfully .</ returnvalue >
</ documentation >
< argument >
< name > success </ name >
< type > BOOLEAN </ type >
< documentation >
< purpose > Pass the last success state returned by the class or any
external code processing the class function results .</ purpose >
</ documentation >
</ argument >
< do >
{ / metadocument }
*/
Function Finalize ( $success )
{
return ( $success );
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
/*
{ metadocument }
< function >
< name > Output </ name >
< type > VOID </ type >
< documentation >
< purpose > Display the results of the OAuth protocol processing .</ purpose >
< usage > Only call this function if you are debugging the OAuth
authorization process and you need to view what was its
results .</ usage >
</ documentation >
< do >
{ / metadocument }
*/
Function Output ()
{
if ( strlen ( $this -> authorization_error )
|| strlen ( $this -> access_token_error )
|| strlen ( $this -> access_token ))
{
?>
<! DOCTYPE HTML PUBLIC " -//W3C//DTD HTML 4.01 Transitional//EN " >
< html >
< head >
< title > OAuth client result </ title >
</ head >
< body >
< h1 > OAuth client result </ h1 >
< ? php
if ( strlen ( $this -> authorization_error ))
{
?>
< p > It was not possible to authorize the application .< ? php
if ( $this -> debug )
{
?>
< br > Authorization error : < ? php echo HtmlSpecialChars ( $this -> authorization_error );
}
?> </p>
< ? php
}
elseif ( strlen ( $this -> access_token_error ))
{
?>
< p > It was not possible to use the application access token .
< ? php
if ( $this -> debug )
{
?>
< br > Error : < ? php echo HtmlSpecialChars ( $this -> access_token_error );
}
?> </p>
< ? php
}
elseif ( strlen ( $this -> access_token ))
{
?>
< p > The application authorization was obtained successfully .
< ? php
if ( $this -> debug )
{
?>
< br > Access token : < ? php echo HtmlSpecialChars ( $this -> access_token );
if ( IsSet ( $this -> access_token_secret ))
{
?>
< br > Access token secret : < ? php echo HtmlSpecialChars ( $this -> access_token_secret );
}
}
?> </p>
< ? php
if ( strlen ( $this -> access_token_expiry ))
{
?>
< p > Access token expiry : < ? php echo $this -> access_token_expiry ; ?> UTC</p>
< ? php
}
}
?>
</ body >
</ html >
< ? php
}
}
/*
{ metadocument }
</ do >
</ function >
{ / metadocument }
*/
};
/*
{ metadocument }
</ class >
{ / metadocument }
*/
2013-07-15 04:56:23 +00:00
?>