setCacheDir() method from your application to enable caching. * Use ->setCacheTTL() to set a time to live in minutes * * TODO: * Clean up the method lookup/validation interface. * Enforce a cache size limit * More complete token based authentication implementation * * REQUIREMENTS: * HTTP_Request from PEAR * SimpleXML (builtin) */ require_once "HTTP/Request.php"; // pear install HTTP_Request class UpcomingWrapper { const base_url = 'http://upcoming.yahooapis.com/services/rest/'; private $cache_dir; // directory to cache in private $cache_ttl = 60; // cache time to live in minutes private $cache = false; // is caching enabled? private $api_key; // api key private $method; // current method (validated) private $params; // parameter array private $requestType; // GET or POST? private $response; // Recordset or null for results private $responseCode; // HTTP response code private $error = false; // error state private $token; // to store a security token (if required) /* LOOKUP TABLE FOR METHOD REQUEST TYPES*/ private $getOrPost = array( "auth"=> HTTP_REQUEST_METHOD_GET, "event"=>array( "getInfo"=> HTTP_REQUEST_METHOD_GET, "search"=> HTTP_REQUEST_METHOD_GET, "getWatchList"=> HTTP_REQUEST_METHOD_GET, "getGroups"=> HTTP_REQUEST_METHOD_GET, "add"=> HTTP_REQUEST_METHOD_POST, "edit"=> HTTP_REQUEST_METHOD_POST, "addTags"=> HTTP_REQUEST_METHOD_POST, "removeTag"=> HTTP_REQUEST_METHOD_POST ), "metro"=> HTTP_REQUEST_METHOD_GET, "state"=> HTTP_REQUEST_METHOD_GET, "country"=> HTTP_REQUEST_METHOD_GET, "venue"=>array( "getInfo"=> HTTP_REQUEST_METHOD_GET, "getList"=> HTTP_REQUEST_METHOD_GET, "search"=> HTTP_REQUEST_METHOD_GET, "add"=> HTTP_REQUEST_METHOD_POST, "edit"=> HTTP_REQUEST_METHOD_POST ), "category"=> HTTP_REQUEST_METHOD_GET, "watchlist"=>array( "add"=> HTTP_REQUEST_METHOD_POST, "remove"=> HTTP_REQUEST_METHOD_POST), "user"=> HTTP_REQUEST_METHOD_GET, "group"=>array( "getInfo"=> HTTP_REQUEST_METHOD_GET, "getMembers"=> HTTP_REQUEST_METHOD_GET, "getEvents"=> HTTP_REQUEST_METHOD_GET, "getMyGroups"=> HTTP_REQUEST_METHOD_GET, "add"=> HTTP_REQUEST_METHOD_POST, "edit"=> HTTP_REQUEST_METHOD_POST, "join"=> HTTP_REQUEST_METHOD_POST, "leave"=> HTTP_REQUEST_METHOD_POST, "addEventTo"=> HTTP_REQUEST_METHOD_POST, "admin.removeEvent"=> HTTP_REQUEST_METHOD_POST ) ); /** All hail the Magic Methods! */ public function __construct($api_key) { $this->api_key = $api_key; } /** This method emulates PHP method calls into API calls. */ public function __call($name,$args) { $params = $args[0]; // should pass just one array $name = str_replace('_','.',$name); // changes _ notation into . notation $this->setMethodParams($name,$params); if ($this->sendRequest()) return $this->getResponse(); return null; } /** * The Next methods are signficiantly less magic, * and fairly self explainatory */ public function setMethodParams($method,$params) { // shortcut method $this->setMethod($method); $this->setParams($params); } public function setMethod($method) { return ($this->method = $this->verifyMethod($method)); } public function setParams($params) { if (is_array($params)) { // only accept parameters if they're an aray return ($this->params = $params); } return false; } public function setCacheDir($dir) { $this->cache = true; return ($this->cache_dir = $dir); } public function setCacheTTL($ttl) { return ($this->cache_ttl = $ttl); } public function getResponse() { return $this->response; } public function countResults() { return ($this->response != null) ? $this->response->countItems() : 0; } public function isError() { return $this->error; } public function getToken() { return $this->token; } public function setToken($token_obj) { return ($this->token = $token_obj); } /** * Take a frob (got from a callback somewhere presumabley) and get a security token with it. */ public function frobToToken($frob) { $client = new UpcomingWrapper($this->api_key); //aaaagghh recusion! $query = $client->auth_getToken(array($frob)); if ($client->isError()) return false; $result = $query->getResults(); $this->token = new UpcomingToken($result[0]); return true; } /** * Returns the URL needed to get the frob */ public function urlToGetFrob() { return "http://upcoming.yahoo.com/services/auth/?api_key={$this->api_key}"; } /** * Sends the request and processes results * If a cached result is available, this will bail to the checkCache method. */ public function sendRequest() { if ($this->error) { // if we have already errorerd $this->displayError(); return false; } $submit = $this->params; $submit['api_key'] = $this->api_key; $submit['method'] = $this->method; if ($this->token) // if we have a security token, use it regardless (should work right?) $submit['token'] = $this->token->token; if ($this->cache) { if ($this->checkCache()) // load a cached result if there is one .... return true; } // Prepare to send the request $req =& new HTTP_Request(self::base_url); $req->setMethod($type); // branch depending on request method if ($this->requestType == HTTP_REQUEST_METHOD_POST) { $req->addPostData = $submit; } else { // build a querystring from the parameters $querystring = self::base_url."?"; $submit = array_map("urlencode",$submit); // urlencode each element individually foreach ($submit as $key=>$item) { $querystring.= "$key=$item&"; } $querystring = rtrim($querystring,"&"); // remove trailing & $req->setURL($querystring); } // Send the request if (!PEAR::isError($req->sendRequest())) { $this->responseCode = $req->getResponseCode(); if ($this->responseCode == 200) { $this->parseResult($req->getResponseBody()); $this->makeCache(); return true; } } $this->parseError($req->getResponseBody()); $this->displayError(); $this->response = null; return false; } /* ** Works out what kind of HTTP Request Method the current API Method requires ** TODO: Make this less ugly :-P */ private function verifyMethod($method) { $methodPath = split('\.',$method); $value = $this->getOrPost; foreach ($methodPath as $elem) { $value = $value[$elem]; if (is_array($elem)) { continue; } // branch if ($value == HTTP_REQUEST_METHOD_GET || $value == HTTP_REQUEST_METHOD_POST) { // End of the tree break; } } if ($value != HTTP_REQUEST_METHOD_GET && $value != HTTP_REQUEST_METHOD_POST) { $this->error = true; $this->error_msg = 'Invalid method! See Upcoming API Documentation for valid methods'; return false; } $this->requestType = $value; return $method; } /** * Parses the result SimpleXMLObject into a Recordset Object which then populates itself accordingly */ private function parseResult($xml_response) { $xml = new SimpleXMLElement($xml_response); $this->response = new UpcomingRecordSet(); $this->response->simpleXmlToRecordSet($xml); $this->numberResults = $this->response->countItems(); } /* ** Parses the error XML and extracts the error message. */ private function parseError($response) { $parser = new SimpleXMLElement($response); $error = $parser->children()->attributes(); $this->error_msg = $error->msg; $this->error = true; } /* * Displays a pretty error message when it all goes horribly wrong */ private function displayError() { echo "
There's been a problem with your Upcoming.org API request.
"; if ($this->method) { echo "Method: method}.php\">{$this->method}
"; } if (count($this->params) > 0) { echo "Parameters:
This generated a {$this->responseCode} code, with the error message:
{$this->error_msg}