1 <?php
2 3 4 5 6 7 8 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 = array();
18 protected $proxy;
19 protected static $default_proxy;
20
21 22 23 24 25 26 27 28 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 41 42 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 53 54
55 function setQueryString($params=NULL){
56 $this->queryString = http_build_query($params,'','&');
57 }
58
59 60 61 62 63 64 65 66 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 79
80 function basicAuth($username, $password) {
81 $this->authUsername = $username;
82 $this->authPassword = $password;
83 }
84
85 86 87
88 function ($header) {
89 $this->customHeaders[] = $header;
90 }
91
92 protected function constructURL(){
93 return "$this->baseURL" . ($this->queryString ? "?$this->queryString" : "");
94 }
95
96 97 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 106 107 108 109 110 111 112
113 public function request($subURL = '', $method = "GET", $data = null, $headers = null, $curlOptions = array()) {
114 $url = $this->baseURL . $subURL;
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);
123 $method = strtoupper($method);
124
125 assert(in_array($method, array('GET','POST','PUT','DELETE','HEAD','OPTIONS')));
126
127 $cachedir = TEMP_FOLDER;
128 $cache_file = md5($url);
129 $cache_path = $cachedir."/xmlresponse_$cache_file";
130
131
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
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
155 if($this->authUsername) curl_setopt($ch, CURLOPT_USERPWD, "$this->authUsername:$this->authPassword");
156
157
158 if($method == 'POST') {
159 curl_setopt($ch, CURLOPT_POST, 1);
160 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
161 }
162
163
164 if(is_array($this->proxy)) {
165 curl_setopt_array($ch, $this->proxy);
166 }
167
168
169 curl_setopt_array($ch, $curlOptions);
170
171
172 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
173 $responseBody = curl_exec($ch);
174 $curlError = curl_error($ch);
175
176
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
194 $store = serialize($response);
195 file_put_contents($cache_path,$store);
196 }
197
198 return $response;
199 }
200
201 202 203 204 205 206 207 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 234 235 236 237 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 259 260 261 262 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){
293 $conv_value = Convert::raw2xml($value);
294 }
295
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 311 312 313 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 330 331 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 343 344 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 368 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 393
394 function xpath($xpath) {
395 return $this->simpleXML()->xpath($xpath);
396 }
397
398 399 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.
-