Skip to content

Instantly share code, notes, and snippets.

@fangel
Created May 3, 2009 12:28
Show Gist options
  • Save fangel/105973 to your computer and use it in GitHub Desktop.
Save fangel/105973 to your computer and use it in GitHub Desktop.
<?php
class CNApi {
public static function getServer() {
// Returns the CNRestServer that will handle our API
$server = new CNRestServer();
// Bind all our API methods to it..
$server->addMethod('misc.echo', array('CNApi', 'misc_echo'));
// Snipped
return $server;
}
public static function misc_echo( $oauth_request ) {
// A debug API method, returns whatever your call it with
$params = $oauth_request->get_parameters();
$rtn = array();
foreach( $params AS $n => $p ) {
if( substr($n, 0, 6) != 'oauth_' ) {
$rtn[$n] = $p;
}
}
return $rtn;
}
}
<?php
class CNRestServer {
private $oauth_request = null;
private $oauth_server = null;
private $methods = array();
public function __construct() {
// Setup the OAuth library
$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
$plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
$this->oauth_server = new OAuthServer(new CNDataStorage());
$this->oauth_server->add_signature_method($hmac_method);
$this->oauth_server->add_signature_method($plaintext_method);
$this->oauth_request = OAuthRequest::from_request();
}
public function addMethod( $name, $callback ) {
// Add a new method to the server
$this->methods[ $name ] = $callback;
}
public function handleCall() {
// Handle a call
list($consumer, $token) = $this->oauth_server->verify_request($this->oauth_request);
// Verify OAuth call, and find the consumer and token in the call
$method = $this->oauth_request->get_parameter('method');
// Do we have a method to call
if( !$method || !isset($this->methods[$method]) ) {
// No or invalid method
throw new Exception('Unknown method: ' . preg_replace('/[^-_.0-9a-zA-Z]/','',$method), 201);
}
$callback = $this->methods[ $method ];
$user_table = new User_table();
$user = $user_table->get( $token->userid, AF::DELAY_SAFE );
// Finds the user tied to the token
if( ! $user ) {
// The user was somehow not found - this shouldn't be possible
throw new Exception('Error trying to load user', 203);
}
if( $user->expired() ) {
// The user has expired
throw new Exception('This user account has expired', 301);
}
$params = $this->oauth_request->get_parameters();
$params['oauth_request'] = $this->oauth_request;
$params['consumer'] = $consumer;
$params['token'] = $token;
$params['user'] = $user;
// Builds a list of parameters the requested method can use
$args = $this->_sortArgs( $callback, $params );
// Filter and sort the list by the parameters the method actually needs
return call_user_func_array( $callback, $args );
}
protected function _sortArgs($callback, $params) {
// Takes a callback and a list or params and filter and
// sort the list by the parameters the method actually needs
if( is_array($callback) ) {
$ref_func = new ReflectionMethod($callback[0], $callback[1]);
} else {
$ref_func = new ReflectionFunction($callback);
}
// Create a reflection on the method
$ref_parameters = $ref_func->getParameters();
// finds the parameters needed for the function via Reflections
$ordered_parameters = array();
foreach($ref_parameters AS $ref_parameter) {
// Run through all the parameters we need
if( isset($params[$ref_parameter->getName()]) ) {
// We have this parameters in the list to choose from
$ordered_parameters[] = $params[$ref_parameter->getName()];
} elseif( $ref_parameter->isDefaultValueAvailable() ) {
// We don't have this parameter, but it's optional
$ordered_parameters[] = $ref_parameter->getDefaultValue();
} else {
// We dont' have this parameter and it wasn't optional, abort!
throw new Exception('Missing parameter ' . $ref_parameter->getName() . '', 202);
$ordered_parameters[] = null;
}
}
return $ordered_parameters;
}
}
<?php
header("Content-Type: text/plain; charset=UTF-8");
try {
// Fetch the server
$server = CNApi::getServer();
// Ask the server to handle the call
$output = $server->handleCall();
// Return the output as JSON
echo json_encode($output);
} catch( Exception $e ) {
// Something terrible happened
header("HTTP/500 Internal Server Error"); // Check if this is how you do it!
echo json_encode( array('error'=>1, 'msg'=>$e->getMessage(), 'code'=>$e->getCode()));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment