Webylon 3.2 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • 1c
    • exchange
      • catalog
  • auth
  • Booking
  • building
    • company
  • cart
    • shipping
    • steppedcheckout
  • Catalog
    • monument
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • RestfulService
  • RestfulService_Response
  • RSSFeed
  • RSSFeed_Entry
  • SapphireSoapServer
  • SS_HTMLValue
  • VersionedRestfulServer
  1 <?php
  2 /**
  3  * RestfulService class allows you to consume various RESTful APIs.
  4  * Through this you could connect and aggregate data of various web services.
  5  * For more info visit wiki documentation - http://doc.silverstripe.org/doku.php?id=restfulservice  
  6  * 
  7  * @package sapphire
  8  * @subpackage integration
  9  */
 10 class RestfulService extends ViewableData {
 11     protected $baseURL;
 12     protected $queryString;
 13     protected $errorTag;
 14     protected $checkErrors;
 15     protected $cache_expire;
 16     protected $authUsername, $authPassword;
 17     protected $customHeaders = array();
 18     protected $proxy;
 19     protected static $default_proxy;
 20     
 21     /**
 22      * Sets default proxy settings for outbound RestfulService connections
 23      *
 24      * @param string $proxy The URL of the proxy to use.
 25      * @param int $port Proxy port
 26      * @param string $user The proxy auth user name
 27      * @param string $password The proxy auth password
 28      * @param boolean $socks Set true to use socks5 proxy instead of http
 29      */
 30     static function set_default_proxy($proxy, $port = 80, $user = "", $password = "", $socks = false) {
 31         self::$default_proxy = array(
 32             CURLOPT_PROXY => $proxy,
 33             CURLOPT_PROXYUSERPWD => "{$user}:{$password}",
 34             CURLOPT_PROXYPORT => $port,
 35             CURLOPT_PROXYTYPE => ($socks ? CURLPROXY_SOCKS5 : CURLPROXY_HTTP)
 36         );
 37     }
 38     
 39     /**
 40     * Creates a new restful service.
 41     * @param string $base Base URL of the web service eg: api.example.com 
 42     * @param int $expiry Set the cache expiry interva. Defaults to 1 hour (3600 seconds)
 43     */
 44     function __construct($base, $expiry=3600){
 45         $this->baseURL = $base;
 46         $this->cache_expire = $expiry;
 47         $this->proxy = self::$default_proxy;
 48         parent::__construct();
 49     }
 50     
 51     /**
 52     * Sets the Query string parameters to send a request.
 53     * @param array $params An array passed with necessary parameters. 
 54     */
 55     function setQueryString($params=NULL){
 56         $this->queryString = http_build_query($params,'','&');
 57     }
 58 
 59     /**
 60      * Set proxy settings for this RestfulService instance
 61      *
 62      * @param string $proxy The URL of the proxy to use.
 63      * @param int $port Proxy port
 64      * @param string $user The proxy auth user name
 65      * @param string $password The proxy auth password
 66      * @param boolean $socks Set true to use socks5 proxy instead of http
 67      */
 68      function setProxy($proxy, $port = 80, $user = "", $password = "", $socks = false) {
 69         $this->proxy = array(
 70             CURLOPT_PROXY => $proxy,
 71             CURLOPT_PROXYUSERPWD => "{$user}:{$password}",
 72             CURLOPT_PROXYPORT => $port,
 73             CURLOPT_PROXYTYPE => ($socks ? CURLPROXY_SOCKS5 : CURLPROXY_HTTP)           
 74         );
 75     }
 76     
 77     /**
 78      * Set basic authentication
 79      */
 80     function basicAuth($username, $password) {
 81         $this->authUsername = $username;
 82         $this->authPassword = $password;
 83     }
 84     
 85     /**
 86      * Set a custom HTTP header
 87      */
 88     function httpHeader($header) {
 89         $this->customHeaders[] = $header;
 90     }
 91     
 92     protected function constructURL(){
 93         return "$this->baseURL" . ($this->queryString ? "?$this->queryString" : "");
 94     }
 95     
 96     /**
 97      * @deprecated Use RestfulService::request()
 98      */
 99     public function connect($subURL = '') {
100         user_error("RestfulService::connect is deprecated; use RestfulService::request", E_USER_NOTICE);
101         return $this->request($subURL)->getBody();
102     }
103     
104     /**
105      * Makes a request to the RESTful server, and return a {@link RestfulService_Response} object for parsing of the result.
106      * @todo Better POST, PUT, DELETE, and HEAD support
107      * @todo Caching of requests - probably only GET and HEAD requestst
108      * @todo JSON support in RestfulService_Response
109      * @todo Pass the response headers to RestfulService_Response
110      *
111      * This is a replacement of {@link connect()}.
112      */
113     public function request($subURL = '', $method = "GET", $data = null, $headers = null, $curlOptions = array()) {
114         $url = $this->baseURL . $subURL; // Url for the request
115         if($this->queryString) {
116             if(strpos($url, '?') !== false) {
117                 $url .= '&' . $this->queryString;
118             } else {
119                 $url .= '?' . $this->queryString;
120             }
121         }
122         $url = str_replace(' ', '%20', $url); // Encode spaces
123         $method = strtoupper($method);
124         
125         assert(in_array($method, array('GET','POST','PUT','DELETE','HEAD','OPTIONS')));
126         
127         $cachedir = TEMP_FOLDER;    // Default silverstripe cache
128         $cache_file = md5($url);    // Encoded name of cache file
129         $cache_path = $cachedir."/xmlresponse_$cache_file";
130         
131         // Check for unexpired cached feed (unless flush is set)
132         if(!isset($_GET['flush']) && @file_exists($cache_path) && @filemtime($cache_path) + $this->cache_expire > time()) {
133             $store = file_get_contents($cache_path);
134             $response = unserialize($store);
135             
136         } else {
137             $ch = curl_init();
138             $timeout = 5;
139             $useragent = "SilverStripe/" . SapphireInfo::Version();
140             @curl_setopt($ch, CURLOPT_URL, $url);
141             @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
142             @curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
143             @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
144             @curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
145             @curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
146         
147             // Add headers
148             if($this->customHeaders) {
149                 $headers = array_merge((array)$this->customHeaders, (array)$headers);
150             }
151         
152             if($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
153         
154             // Add authentication
155             if($this->authUsername) curl_setopt($ch, CURLOPT_USERPWD, "$this->authUsername:$this->authPassword");
156         
157             // Add fields to POST requests
158             if($method == 'POST') {
159                 curl_setopt($ch, CURLOPT_POST, 1);
160                 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
161             }
162             
163             // Apply proxy settings
164             if(is_array($this->proxy)) {
165                 curl_setopt_array($ch, $this->proxy);
166             }
167             
168             // Set any custom options passed to the request() function
169             curl_setopt_array($ch, $curlOptions);
170 
171             // Run request
172             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
173             $responseBody = curl_exec($ch);
174             $curlError = curl_error($ch);
175             
176             // Problem verifying the server SSL certificate; just ignore it as it's not mandatory
177             if(strpos($curlError,'14090086') !== false) {
178                 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
179                 $responseBody = curl_exec($ch);
180                 $curlError = curl_error($ch);
181             }
182             
183             if($responseBody === false) {
184                 user_error("Curl Error:" . $curlError, E_USER_WARNING);
185                 return;
186             }
187 
188             $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
189             $response = new RestfulService_Response($responseBody, curl_getinfo($ch, CURLINFO_HTTP_CODE));
190         
191             curl_close($ch);
192 
193             // Serialise response object and write to cache
194             $store = serialize($response);
195             file_put_contents($cache_path,$store);
196         }
197 
198         return $response;
199     }
200     
201     /**
202     * Gets attributes as an array, of a particular type of element.
203     * Example : <photo id="2636" owner="123" secret="ab128" server="2"> 
204     * returns id, owner,secret and sever attribute values of all such photo elements.
205     * @param string $xml The source xml to parse, this could be the original response received.
206     * @param string $collection The name of parent node which wraps the elements, if available
207     * @param string $element The element we need to extract the attributes.
208     */
209     
210     public function getAttributes($xml, $collection=NULL, $element=NULL){
211         $xml = new SimpleXMLElement($xml);
212         $output = new DataObjectSet();
213         
214         if($collection)
215             $childElements = $xml->{$collection};
216         if($element)
217             $childElements = $xml->{$collection}->{$element};
218         
219         if($childElements){
220             foreach($childElements as $child){
221                 $data = array();
222                 foreach($child->attributes() as $key => $value){
223                     $data["$key"] = Convert::raw2xml($value);
224                 }
225                 $output->push(new ArrayData($data));
226             }
227         }
228         return $output;
229         
230     }
231     
232     /**
233     * Gets an attribute of a particular element.
234     * @param string $xml The source xml to parse, this could be the original response received.
235     * @param string $collection The name of the parent node which wraps the element, if available
236     * @param string $element The element we need to extract the attribute
237     * @param string $attr The name of the attribute
238     */
239     
240     public function getAttribute($xml, $collection=NULL, $element=NULL, $attr){
241         $xml = new SimpleXMLElement($xml);
242         $attr_value = "";
243     
244         if($collection)
245             $childElements = $xml->{$collection};
246         if($element)
247             $childElements = $xml->{$collection}->{$element};
248     
249         if($childElements)
250             $attr_value = (string) $childElements[$attr];
251     
252         return Convert::raw2xml($attr_value);
253         
254     }
255         
256     
257     /**
258     * Gets set of node values as an array. 
259     * When you get to the depth in the hierachchy use node_child_subchild syntax to get the value.
260     * @param string $xml The the source xml to parse, this could be the original response received.
261     * @param string $collection The name of parent node which wraps the elements, if available
262     * @param string $element The element we need to extract the node values.
263     */
264     
265     public function getValues($xml, $collection=NULL, $element=NULL){
266         $xml = new SimpleXMLElement($xml);
267         $output = new DataObjectSet();
268         
269             $childElements = $xml;
270         if($collection)
271             $childElements = $xml->{$collection};
272         if($element)
273             $childElements = $xml->{$collection}->{$element};
274         
275         if($childElements){
276             foreach($childElements as $child){
277                 $data = array();
278                 $this->getRecurseValues($child,$data);          
279                 $output->push(new ArrayData($data));
280             }
281         }
282         return $output;
283     }
284     
285     protected function getRecurseValues($xml,&$data,$parent=""){
286         $conv_value = "";
287         $child_count = 0;
288         foreach($xml as $key=>$value)
289         {
290             $child_count++;    
291             $k = ($parent == "") ? (string)$key : $parent . "_" . (string)$key;
292             if($this->getRecurseValues($value,$data,$k) == 0){  // no childern, aka "leaf node"
293                    $conv_value = Convert::raw2xml($value);
294             }  
295             //Review the fix for similar node names overriding it's predecessor
296             if(array_key_exists($k, $data) == true) {   
297                 $data[$k] = $data[$k] . ",". $conv_value;       
298             }
299             else {
300                  $data[$k] = $conv_value;
301             }
302             
303             
304         }
305         return $child_count;
306             
307     }
308     
309     /**
310     * Gets a single node value. 
311     * @param string $xml The source xml to parse, this could be the original response received.
312     * @param string $collection The name of parent node which wraps the elements, if available
313     * @param string $element The element we need to extract the node value.
314     */
315     
316     function getValue($xml, $collection=NULL, $element=NULL){
317         $xml = new SimpleXMLElement($xml);
318         
319         if($collection)
320             $childElements = $xml->{$collection};
321         if($element)
322             $childElements = $xml->{$collection}->{$element};
323         
324         if($childElements)
325             return Convert::raw2xml($childElements);
326     }
327     
328     /**
329     * Searches for a node in document tree and returns it value. 
330     * @param string $xml source xml to parse, this could be the original response received.
331     * @param string $node Node to search for
332     */
333     function searchValue($xml, $node=NULL){
334         $xml = new SimpleXMLElement($xml);
335         $childElements = $xml->xpath($node);
336         
337         if($childElements)
338             return Convert::raw2xml($childElements[0]);
339     }
340     
341     /**
342     * Searches for a node in document tree and returns its attributes. 
343     * @param string $xml the source xml to parse, this could be the original response received.
344     * @param string $node Node to search for
345     */
346     function searchAttributes($xml, $node=NULL){
347         $xml = new SimpleXMLElement($xml);
348         $output = new DataObjectSet();
349     
350         $childElements = $xml->xpath($node);
351         
352         if($childElements)
353         foreach($childElements as $child){
354         $data = array();
355             foreach($child->attributes() as $key => $value){
356                 $data["$key"] = Convert::raw2xml($value);
357             }
358             
359             $output->push(new ArrayData($data));
360         }
361         
362         return $output;
363     }
364 }
365 
366 /**
367  * @package sapphire
368  * @subpackage integration
369  */
370 class RestfulService_Response extends SS_HTTPResponse {
371     protected $simpleXML;
372     
373     function __construct($body, $statusCode = 200, $headers = null) {
374         $this->setbody($body);
375         $this->setStatusCode($statusCode);
376         $this->headers = $headers;
377     }
378     
379     function simpleXML() {
380         if(!$this->simpleXML) {
381             try {
382                 $this->simpleXML = new SimpleXMLElement($this->body);
383             }
384             catch(Exception $e) {
385                 user_error("String could not be parsed as XML. " . $e, E_USER_WARNING);
386             }
387         }
388         return $this->simpleXML;
389     }
390     
391     /**
392      * Return an array of xpath matches
393      */
394     function xpath($xpath) {
395         return $this->simpleXML()->xpath($xpath);
396     }
397     
398     /**
399      * Return the first xpath match
400      */
401     function xpath_one($xpath) {
402         $items = $this->xpath($xpath);
403         return $items[0];
404     }
405 }
406 
407 ?>
408 
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.2 API Docs API documentation generated by ApiGen 2.8.0