The new RestfulService.php
<?php
/**
* RestfulService class allows you to consume various RESTful APIs.
* Through this you could connect and aggregate data of various web services.
*/
class RestfulService extends ViewableData {
protected $baseURL;
protected $queryString;
protected $rawXML;
protected $errorTag;
protected $cachedir;
protected $cache_location;
protected $cache_expires;
protected $cache_lifetime;
protected $source; // cache or live
protected $cashed_Content;
function __construct($base,$locationname,$lifetime){
$this->baseURL = $base;
$this->cache_lifetime = $lifetime;
if (isset($_ENV["TEMP"]))
$cachedir=$_ENV["TEMP"]."/silverstripe-cache";
else if (isset($_ENV["TMP"]))
$cachedir=$_ENV["TMP"]."/silverstripe-cache";
else if (isset($_ENV["TMPDIR"]))
$cachedir=$_ENV["TMPDIR"]."/silverstripe-cache";
else
// Default Cache Directory
$cachedir="/tmp";
$cachedir=str_replace('\\\\','/',$cachedir);
if (substr($cachedir,-1)!='/') $cachedir.='/';
$this->cache_location = $cachedir.$locationname;
}
/**
* Sets the Query string parameters to send a request.
* @param params An array passed with necessary parameters.
*/
function setQueryString($params=NULL){
$this->queryString = http_build_query($params,'','&');
}
protected function constructURL(){
return "$this->baseURL?$this->queryString";
}
/**
* Connects to the RESTful service and gets its response.
* TODO implement authentication via cURL for
*/
function connect(){
$url = $this->constructURL();
if ($this->readcache()) { //TRUE MEANS THAT CASH WILL BE READ
$this->source = 'cache';
}else{
$this->source = 'live';
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$this->rawXML = curl_exec($ch);
curl_close($ch);
//Debug::show($url);
//Try using file_get_contents if cURL is not installed in your system.
//$this->rawXML = file_get_contents($url);
if($this->rawXML != "")
if($this->checkErrors == true)
return $this->errorCatch($this->rawXML);
else
return $this->rawXML;
else
user_error("Invalid Response (maybe your calling to wrong URL or server unavailable)", E_USER_ERROR);
}
}
function readcache()
{
if (file_exists($this->cache_location) && filemtime($this->cache_location)<time()){
$content=@file_get_contents($this->cache_location);
if ($content==false) return false;
$intweather = unserialize($content);
$this->cashed_Content = $intweather;
return true;
}else{
return false;
}
}
function writecache($output) {
$cache_expires= time() + $this->cache_lifetime;
$fp = fopen($this->cache_location, "w");
fwrite($fp, serialize($output));
fclose($fp);
}
/**
* Gets attributes as an array, of a particular type of element.
* @params xml - the source xml to parse, this could be the original response received.
* @params collection - parent node which wraps the elements, if available
* @params element - element we need to extract the attributes.
* Example : <photo id="2636" owner="123" secret="ab128" server="2">
* returns id, owner,secret and sever attribute values of all such photo elements.
*/
function getAttributes($xml, $collection=NULL, $element=NULL){
if ($this->source == 'live'){
$xml = new SimpleXMLElement($xml);
$output = new DataObjectSet();
if($collection)
$childElements = $xml->{$collection};
if($element)
$childElements = $xml->{$collection}->{$element};
if($childElements){
foreach($childElements as $child){
$data = array();
foreach($child->attributes() as $key => $value){
$data["$key"] = Convert::raw2xml($value);
}
$output->push(new ArrayData($data));
}
}
//Debug::show($output);
}else if ($this->source == 'cache'){
$output=$this->cashed_Content;
}
return $output;
}
/**
* Gets an attribute of a particular element.
* @params xml - the source xml to parse, this could be the original response received.
* @params collection - parent node which wraps the element, if available
* @params element - element we need to extract the attribute
* @params attr - name of the attribute
*/
function getAttribute($xml, $collection=NULL, $element=NULL, $attr){
if ($this->source == 'live'){
$xml = new SimpleXMLElement($xml);
$attr_value = "";
if($collection)
$childElements = $xml->{$collection};
if($element)
$childElements = $xml->{$collection}->{$element};
if($childElements)
$attr_value = (string) $childElements[$attr];
$this->output= Convert::raw2xml($attr_value);
$this->writecache($this->output);
}else if ($this->source == 'cache'){
$output=$this->cashed_Content;
}
return $output;
}
/**
* Gets set of node values as an array.
* When you get to the depth in the hierachchy use node_child_subchild syntax to get the value.
* @params xml - the source xml to parse, this could be the original response received.
* @params collection - parent node which wraps the elements, if available
* @params element - element we need to extract the node values.
*/
function getValues($xml, $collection=NULL, $element=NULL){
if ($this->source == 'live'){
$xml = new SimpleXMLElement($xml);
$output = new DataObjectSet();
$childElements = $xml;
if($collection)
$childElements = $xml->{$collection};
if($element)
$childElements = $xml->{$collection}->{$element};
if($childElements){
foreach($childElements as $child){
$data = array();
$this->getRecurseValues($child,$data);
$output->push(new ArrayData($data));
}
}
$this->writecache($output);
}else if ($this->source == 'cache'){
$output =$this->cashed_Content;
}
return $output;
}
protected function getRecurseValues($xml,&$data,$parent=""){
$child_count = 0;
foreach($xml as $key=>$value)
{
$child_count++;
$k = ($parent == "") ? (string)$key : $parent . "_" . (string)$key;
if($this->getRecurseValues($value,$data,$k) == 0) // no childern, aka "leaf node"
$data[$k] = Convert::raw2xml($value);
}
return $child_count;
}
/**
* Gets a single node value.
* @params xml - the source xml to parse, this could be the original response received.
* @params collection - parent node which wraps the elements, if available
* @params element - element we need to extract the node value.
*/
function getValue($xml, $collection=NULL, $element=NULL){
if ($this->source == 'live'){
$xml = new SimpleXMLElement($xml);
if($collection)
$childElements = $xml->{$collection};
if($element)
$childElements = $xml->{$collection}->{$element};
if($childElements)
$output = Convert::raw2xml($childElements);
$this->writecache($output);
}else if ($this->source == 'cache'){
$output = $this->cashed_Content;
}
return $output;
}
function searchValue($xml, $node=NULL){
if ($this->source == 'live'){
$xml = new SimpleXMLElement($xml);
$childElements = $xml->xpath($node);
if($childElements)
$output = Convert::raw2xml($childElements[0]);
$this->writecache($output);
}else if ($this->source == 'cache'){
$output =$this->cashed_Content;
}
return $output;
}
function searchAttributes($xml, $node=NULL){
echo $this->source;
if ($this->source == 'live'){
$xml = new SimpleXMLElement($xml);
$output = new DataObjectSet();
$childElements = $xml->xpath($node);
if($childElements)
foreach($childElements as $child){
$data = array();
foreach($child->attributes() as $key => $value){
$data["$key"] = Convert::raw2xml($value);
}
$output->push(new ArrayData($data));
}
//Debug::show($output);
$this->writecache($output);
}else if ($this->source == 'cache'){
$output =$this->cashed_Content;
}
return $output;
}
}
?>
The new mashupsample.php:
<?
class MashupSample extends Page {
static $db = array(
);
static $has_one = array(
);
}
class MashupSample_Controller extends Page_Controller {
//Test on AMAZON AWS testing
function AmazonProducts(){
$cash_lifetime=3*60*60; // 3 hours
$location_name="Amazon"; //Has to be unique because for every new RestfulService you have a new cash file
$feed="http://ecs.amazonaws.com/onca/xml";
$amazon = new RestfulService($feed,$location_name,$cash_lifetime);
$params = array(
"Service"=>"AWSECommerceService",
"AWSAccessKeyId"=>"0QZ1AAT31TZ9RNVANY82",
"Operation"=>"ItemSearch",
"SearchIndex"=>"Books",
"Title"=>"Harry Potter"
);
$amazon->setQueryString($params);
$conn = $amazon->connect();
$result = $amazon->getValues($conn, "Items", "Item");
//Debug::show($result);
return $result;
}
function YahooWeather(){
$cash_lifetime=0; // no caching
$location_name="YahooWeather"; //Has to be unique because for every new RestfulService you have a new cash file
$feed="http://localhost/projects/forecastrss.xml";
$yw = new RestfulService($feed,$location_name,$cash_lifetime);
$params = array(
"u"=>"C",
"p"=>"AUXX0118"
);
$yw->setQueryString($params);
$conn = $yw->connect();
$result = $yw->searchAttributes($conn, "//yweather:condition");
return $result;
}
}
?>