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

Packages

  • auth
  • Booking
  • cart
    • shipping
    • steppedcheckout
  • Catalog
  • 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->getAbsoluteRequestURL($subURL);
115 
116         $method = strtoupper($method);
117         
118         assert(in_array($method, array('GET','POST','PUT','DELETE','HEAD','OPTIONS')));
119         
120         $cachedir = TEMP_FOLDER;    // Default silverstripe cache
121         $cache_file = md5($url);    // Encoded name of cache file
122         $cache_path = $cachedir."/xmlresponse_$cache_file";
123         
124         // Check for unexpired cached feed (unless flush is set)
125         if(!isset($_GET['flush']) && @file_exists($cache_path) && @filemtime($cache_path) + $this->cache_expire > time()) {
126             $store = file_get_contents($cache_path);
127             $response = unserialize($store);
128             
129         } else {
130             $ch = curl_init();
131             $timeout = 5;
132             $useragent = "SilverStripe/" . SapphireInfo::Version();
133             @curl_setopt($ch, CURLOPT_URL, $url);
134             @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
135             @curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
136             @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
137             @curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
138             @curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
139         
140             // Add headers
141             if($this->customHeaders) {
142                 $headers = array_merge((array)$this->customHeaders, (array)$headers);
143             }
144         
145             if($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
146         
147             // Add authentication
148             if($this->authUsername) curl_setopt($ch, CURLOPT_USERPWD, "$this->authUsername:$this->authPassword");
149         
150             // Add fields to POST requests
151             if($method == 'POST') {
152                 curl_setopt($ch, CURLOPT_POST, 1);
153                 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
154             }
155             
156             // Apply proxy settings
157             if(is_array($this->proxy)) {
158                 curl_setopt_array($ch, $this->proxy);
159             }
160             
161             // Set any custom options passed to the request() function
162             curl_setopt_array($ch, $curlOptions);
163 
164             // Run request
165             curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
166             $responseBody = curl_exec($ch);
167             $curlError = curl_error($ch);
168             
169             // Problem verifying the server SSL certificate; just ignore it as it's not mandatory
170             if(strpos($curlError,'14090086') !== false) {
171                 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
172                 $responseBody = curl_exec($ch);
173                 $curlError = curl_error($ch);
174             }
175             
176             if($responseBody === false) {
177                 user_error("Curl Error:" . $curlError, E_USER_WARNING);
178                 return;
179             }
180 
181             $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
182             $response = new RestfulService_Response($responseBody, curl_getinfo($ch, CURLINFO_HTTP_CODE));
183         
184             curl_close($ch);
185 
186             // Serialise response object and write to cache
187             $store = serialize($response);
188             file_put_contents($cache_path,$store);
189         }
190 
191         return $response;
192     }
193     
194       /** 
195       * Returns a full request url
196       * @param string 
197       */ 
198      function getAbsoluteRequestURL($subURL) {
199          $url = $this->baseURL . $subURL; // Url for the request
200          if($this->queryString) {
201              if(strpos($url, '?') !== false) {
202                  $url .= '&' . $this->queryString;
203              } else {
204                  $url .= '?' . $this->queryString;
205              }
206          }
207          
208          return str_replace(' ', '%20', $url); // Encode spaces
209      }
210      
211     /**
212     * Gets attributes as an array, of a particular type of element.
213     * Example : <photo id="2636" owner="123" secret="ab128" server="2"> 
214     * returns id, owner,secret and sever attribute values of all such photo elements.
215     * @param string $xml The source xml to parse, this could be the original response received.
216     * @param string $collection The name of parent node which wraps the elements, if available
217     * @param string $element The element we need to extract the attributes.
218     */
219     
220     public function getAttributes($xml, $collection=NULL, $element=NULL){
221         $xml = new SimpleXMLElement($xml);
222         $output = new DataObjectSet();
223         
224         if($collection)
225             $childElements = $xml->{$collection};
226         if($element)
227             $childElements = $xml->{$collection}->{$element};
228         
229         if($childElements){
230             foreach($childElements as $child){
231                 $data = array();
232                 foreach($child->attributes() as $key => $value){
233                     $data["$key"] = Convert::raw2xml($value);
234                 }
235                 $output->push(new ArrayData($data));
236             }
237         }
238         return $output;
239         
240     }
241     
242     /**
243     * Gets an attribute of a particular element.
244     * @param string $xml The source xml to parse, this could be the original response received.
245     * @param string $collection The name of the parent node which wraps the element, if available
246     * @param string $element The element we need to extract the attribute
247     * @param string $attr The name of the attribute
248     */
249     
250     public function getAttribute($xml, $collection=NULL, $element=NULL, $attr){
251         $xml = new SimpleXMLElement($xml);
252         $attr_value = "";
253     
254         if($collection)
255             $childElements = $xml->{$collection};
256         if($element)
257             $childElements = $xml->{$collection}->{$element};
258     
259         if($childElements)
260             $attr_value = (string) $childElements[$attr];
261     
262         return Convert::raw2xml($attr_value);
263         
264     }
265         
266     
267     /**
268     * Gets set of node values as an array. 
269     * When you get to the depth in the hierachchy use node_child_subchild syntax to get the value.
270     * @param string $xml The the source xml to parse, this could be the original response received.
271     * @param string $collection The name of parent node which wraps the elements, if available
272     * @param string $element The element we need to extract the node values.
273     */
274     
275     public function getValues($xml, $collection=NULL, $element=NULL){
276         $xml = new SimpleXMLElement($xml);
277         $output = new DataObjectSet();
278         
279             $childElements = $xml;
280         if($collection)
281             $childElements = $xml->{$collection};
282         if($element)
283             $childElements = $xml->{$collection}->{$element};
284         
285         if($childElements){
286             foreach($childElements as $child){
287                 $data = array();
288                 $this->getRecurseValues($child,$data);          
289                 $output->push(new ArrayData($data));
290             }
291         }
292         return $output;
293     }
294     
295     protected function getRecurseValues($xml,&$data,$parent=""){
296         $conv_value = "";
297         $child_count = 0;
298         foreach($xml as $key=>$value)
299         {
300             $child_count++;    
301             $k = ($parent == "") ? (string)$key : $parent . "_" . (string)$key;
302             if($this->getRecurseValues($value,$data,$k) == 0){  // no childern, aka "leaf node"
303                    $conv_value = Convert::raw2xml($value);
304             }  
305             //Review the fix for similar node names overriding it's predecessor
306             if(array_key_exists($k, $data) == true) {   
307                 $data[$k] = $data[$k] . ",". $conv_value;       
308             }
309             else {
310                  $data[$k] = $conv_value;
311             }
312             
313             
314         }
315         return $child_count;
316             
317     }
318     
319     /**
320     * Gets a single node value. 
321     * @param string $xml The source xml to parse, this could be the original response received.
322     * @param string $collection The name of parent node which wraps the elements, if available
323     * @param string $element The element we need to extract the node value.
324     */
325     
326     function getValue($xml, $collection=NULL, $element=NULL){
327         $xml = new SimpleXMLElement($xml);
328         
329         if($collection)
330             $childElements = $xml->{$collection};
331         if($element)
332             $childElements = $xml->{$collection}->{$element};
333         
334         if($childElements)
335             return Convert::raw2xml($childElements);
336     }
337     
338     /**
339     * Searches for a node in document tree and returns it value. 
340     * @param string $xml source xml to parse, this could be the original response received.
341     * @param string $node Node to search for
342     */
343     function searchValue($xml, $node=NULL){
344         $xml = new SimpleXMLElement($xml);
345         $childElements = $xml->xpath($node);
346         
347         if($childElements)
348             return Convert::raw2xml($childElements[0]);
349     }
350     
351     /**
352     * Searches for a node in document tree and returns its attributes. 
353     * @param string $xml the source xml to parse, this could be the original response received.
354     * @param string $node Node to search for
355     */
356     function searchAttributes($xml, $node=NULL){
357         $xml = new SimpleXMLElement($xml);
358         $output = new DataObjectSet();
359     
360         $childElements = $xml->xpath($node);
361         
362         if($childElements)
363         foreach($childElements as $child){
364         $data = array();
365             foreach($child->attributes() as $key => $value){
366                 $data["$key"] = Convert::raw2xml($value);
367             }
368             
369             $output->push(new ArrayData($data));
370         }
371         
372         return $output;
373     }
374 }
375 
376 /**
377  * @package sapphire
378  * @subpackage integration
379  */
380 class RestfulService_Response extends SS_HTTPResponse {
381     protected $simpleXML;
382     
383     function __construct($body, $statusCode = 200, $headers = null) {
384         $this->setbody($body);
385         $this->setStatusCode($statusCode);
386         $this->headers = $headers;
387     }
388     
389     function simpleXML() {
390         if(!$this->simpleXML) {
391             try {
392                 $this->simpleXML = new SimpleXMLElement($this->body);
393             }
394             catch(Exception $e) {
395                 user_error("String could not be parsed as XML. " . $e, E_USER_WARNING);
396             }
397         }
398         return $this->simpleXML;
399     }
400     
401     /**
402      * Return an array of xpath matches
403      */
404     function xpath($xpath) {
405         return $this->simpleXML()->xpath($xpath);
406     }
407     
408     /**
409      * Return the first xpath match
410      */
411     function xpath_one($xpath) {
412         $items = $this->xpath($xpath);
413         return $items[0];
414     }
415 }
416 
417 ?>
418 
[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.1 API Docs API documentation generated by ApiGen 2.8.0