· 6 years ago · Feb 19, 2020, 02:04 PM
1<?php defined('BASEPATH') OR exit('No direct script access allowed');
2/**
3 * CodeIgniter REST Class
4 *
5 * Make REST requests to RESTful services with simple syntax.
6 *
7 * @package CodeIgniter
8 * @subpackage Libraries
9 * @category Libraries
10 * @author Philip Sturgeon
11 * @author Chris Kacerguis
12 * @created 04/06/2009
13 * @license http://philsturgeon.co.uk/code/dbad-license
14 * @link http://getsparks.org/packages/restclient/show
15 */
16
17class REST
18{
19 protected $_ci;
20
21 protected $supported_formats = array(
22 'xml' => 'application/xml',
23 'json' => 'application/json',
24 'serialize' => 'application/vnd.php.serialized',
25 'php' => 'text/plain',
26 'csv' => 'text/csv'
27 );
28
29 protected $auto_detect_formats = array(
30 'application/xml' => 'xml',
31 'text/xml' => 'xml',
32 'application/json' => 'json',
33 'text/json' => 'json',
34 'text/csv' => 'csv',
35 'application/csv' => 'csv',
36 'application/vnd.php.serialized' => 'serialize'
37 );
38
39 protected $rest_server;
40 protected $format;
41 protected $mime_type;
42
43 protected $http_auth = null;
44 protected $http_user = null;
45 protected $http_pass = null;
46
47 protected $api_name = 'X-API-KEY';
48 protected $api_key = null;
49
50 protected $ssl_verify_peer = null;
51 protected $ssl_cainfo = null;
52
53 protected $send_cookies = null;
54 protected $response_string;
55
56 function __construct($config = array())
57 {
58 $this->_ci =& get_instance();
59 log_message('debug', 'REST Class Initialized');
60
61 /* Not using Sparks? You bloody well should be.
62 | If you are going to be a stick in the mud then do it the old fashioned way
63
64 $this->_ci->load->library('curl');
65 */
66
67 // Load the cURL spark which this is dependant on
68 $this->_ci->load->spark('curl/1.2.0');
69
70 // If a URL was passed to the library
71 empty($config) OR $this->initialize($config);
72 }
73
74 function __destruct()
75 {
76 $this->_ci->curl->set_defaults();
77 }
78
79 /**
80 * initialize
81 *
82 * @access public
83 * @author Phil Sturgeon
84 * @author Chris Kacerguis
85 * @version 1.0
86 */
87 public function initialize($config)
88 {
89 $this->rest_server = @$config['server'];
90
91 if (substr($this->rest_server, -1, 1) != '/')
92 {
93 $this->rest_server .= '/';
94 }
95
96 isset($config['send_cookies']) && $this->send_cookies = $config['send_cookies'];
97
98 isset($config['api_name']) && $this->api_name = $config['api_name'];
99 isset($config['api_key']) && $this->api_key = $config['api_key'];
100
101 isset($config['http_auth']) && $this->http_auth = $config['http_auth'];
102 isset($config['http_user']) && $this->http_user = $config['http_user'];
103 isset($config['http_pass']) && $this->http_pass = $config['http_pass'];
104
105 isset($config['ssl_verify_peer']) && $this->ssl_verify_peer = $config['ssl_verify_peer'];
106 isset($config['ssl_cainfo']) && $this->ssl_cainfo = $config['ssl_cainfo'];
107
108 }
109
110 /**
111 * get
112 *
113 * @access public
114 * @author Phil Sturgeon
115 * @version 1.0
116 */
117 public function get($uri, $params = array(), $format = NULL)
118 {
119 if ($params)
120 {
121 $uri .= '?'.(is_array($params) ? http_build_query($params) : $params);
122 }
123
124 return $this->_call('get', $uri, NULL, $format);
125 }
126
127 /**
128 * post
129 *
130 * @access public
131 * @author Phil Sturgeon
132 * @version 1.0
133 */
134 public function post($uri, $params = array(), $format = NULL)
135 {
136 return $this->_call('post', $uri, $params, $format);
137 }
138
139 /**
140 * put
141 *
142 * @access public
143 * @author Phil Sturgeon
144 * @version 1.0
145 */
146 public function put($uri, $params = array(), $format = NULL)
147 {
148 return $this->_call('put', $uri, $params, $format);
149 }
150
151 /**
152 * patch
153 *
154 * @access public
155 * @author Dmitry Serzhenko
156 * @version 1.0
157 */
158 public function patch($uri, $params = array(), $format = NULL)
159 {
160 return $this->_call('patch', $uri, $params, $format);
161 }
162
163 /**
164 * delete
165 *
166 * @access public
167 * @author Phil Sturgeon
168 * @version 1.0
169 */
170 public function delete($uri, $params = array(), $format = NULL)
171 {
172 return $this->_call('delete', $uri, $params, $format);
173 }
174
175 /**
176 * api_key
177 *
178 * @access public
179 * @author Phil Sturgeon
180 * @version 1.0
181 */
182 public function api_key($key, $name = FALSE)
183 {
184 $this->api_key = $key;
185
186 if ($name !== FALSE)
187 {
188 $this->api_name = $name;
189 }
190
191 }
192
193 /**
194 * language
195 *
196 * @access public
197 * @author Phil Sturgeon
198 * @version 1.0
199 */
200 public function language($lang)
201 {
202 if (is_array($lang))
203 {
204 $lang = implode(', ', $lang);
205 }
206
207 $this->_ci->curl->http_header('Accept-Language', $lang);
208 }
209
210 /**
211 * header
212 *
213 * @access public
214 * @author David Genelid
215 * @version 1.0
216 */
217 public function header($header)
218 {
219 $this->_ci->curl->http_header($header);
220 }
221
222 /**
223 * _call
224 *
225 * @access protected
226 * @author Phil Sturgeon
227 * @version 1.0
228 */
229 protected function _call($method, $uri, $params = array(), $format = NULL)
230 {
231 if ($format !== NULL)
232 {
233 $this->format($format);
234 }
235
236 $this->http_header('Accept', $this->mime_type);
237
238 // Initialize cURL session
239 $this->_ci->curl->create($this->rest_server.$uri);
240
241
242 // If using ssl set the ssl verification value and cainfo
243 // contributed by: https://github.com/paulyasi
244 if ($this->ssl_verify_peer === FALSE)
245 {
246 $this->_ci->curl->ssl(FALSE);
247 }
248 elseif ($this->ssl_verify_peer === TRUE)
249 {
250 $this->ssl_cainfo = getcwd() . $this->ssl_cainfo;
251 $this->_ci->curl->ssl(TRUE, 2, $this->ssl_cainfo);
252 }
253
254 // If authentication is enabled use it
255 if ($this->http_auth != '' && $this->http_user != '')
256 {
257 $this->_ci->curl->http_login($this->http_user, $this->http_pass, $this->http_auth);
258 }
259
260 // If we have an API Key, then use it
261 if ($this->api_key != '')
262 {
263 $this->_ci->curl->http_header($this->api_name, $this->api_key);
264 }
265
266 // Send cookies with curl
267 if ($this->send_cookies != '')
268 {
269
270 $this->_ci->curl->set_cookies( $_COOKIE );
271
272 }
273
274 // Set the Content-Type (contributed by https://github.com/eriklharper)
275 $this->http_header('Content-type', $this->mime_type);
276
277
278 // We still want the response even if there is an error code over 400
279 $this->_ci->curl->option('failonerror', FALSE);
280
281 // Call the correct method with parameters
282 $this->_ci->curl->{$method}($params);
283
284 // Execute and return the response from the REST server
285 $response = $this->_ci->curl->execute();
286
287 // Format and return
288 return $this->_format_response($response);
289 }
290
291 /**
292 * initialize
293 *
294 * If a type is passed in that is not supported, use it as a mime type
295 *
296 * @access public
297 * @author Phil Sturgeon
298 * @version 1.0
299 */
300 public function format($format)
301 {
302 if (array_key_exists($format, $this->supported_formats))
303 {
304 $this->format = $format;
305 $this->mime_type = $this->supported_formats[$format];
306 }
307
308 else
309 {
310 $this->mime_type = $format;
311 }
312
313 return $this;
314 }
315
316 /**
317 * debug
318 *
319 * @access public
320 * @author Phil Sturgeon
321 * @version 1.0
322 */
323 public function debug()
324 {
325 $request = $this->_ci->curl->debug_request();
326
327 echo "=============================================<br/>\n";
328 echo "<h2>REST Test</h2>\n";
329 echo "=============================================<br/>\n";
330 echo "<h3>Request</h3>\n";
331 echo $request['url']."<br/>\n";
332 echo "=============================================<br/>\n";
333 echo "<h3>Response</h3>\n";
334
335 if ($this->response_string)
336 {
337 echo "<code>".nl2br(htmlentities($this->response_string))."</code><br/>\n\n";
338 }
339
340 else
341 {
342 echo "No response<br/>\n\n";
343 }
344
345 echo "=============================================<br/>\n";
346
347 if ($this->_ci->curl->error_string)
348 {
349 echo "<h3>Errors</h3>";
350 echo "<strong>Code:</strong> ".$this->_ci->curl->error_code."<br/>\n";
351 echo "<strong>Message:</strong> ".$this->_ci->curl->error_string."<br/>\n";
352 echo "=============================================<br/>\n";
353 }
354
355 echo "<h3>Call details</h3>";
356 echo "<pre>";
357 print_r($this->_ci->curl->info);
358 echo "</pre>";
359
360 }
361
362
363 /**
364 * status
365 *
366 * @access public
367 * @author Phil Sturgeon
368 * @version 1.0
369 */
370 // Return HTTP status code
371 public function status()
372 {
373 return $this->info('http_code');
374 }
375
376 /**
377 * info
378 *
379 * Return curl info by specified key, or whole array
380 *
381 * @access public
382 * @author Phil Sturgeon
383 * @version 1.0
384 */
385 public function info($key = null)
386 {
387 return $key === null ? $this->_ci->curl->info : @$this->_ci->curl->info[$key];
388 }
389
390 /**
391 * option
392 *
393 * Set custom CURL options
394 *
395 * @access public
396 * @author Phil Sturgeon
397 * @version 1.0
398 */
399 //
400 public function option($code, $value)
401 {
402 $this->_ci->curl->option($code, $value);
403 }
404
405 /**
406 * http_header
407 *
408 * @access public
409 * @author Phil Sturgeon
410 * @version 1.0
411 */
412 public function http_header($header, $content = NULL)
413 {
414 // Did they use a single argument or two?
415 $params = $content ? array($header, $content) : array($header);
416
417 // Pass these attributes on to the curl library
418 call_user_func_array(array($this->_ci->curl, 'http_header'), $params);
419 }
420
421 /**
422 * _format_response
423 *
424 * @access public
425 * @author Phil Sturgeon
426 * @version 1.0
427 */
428 protected function _format_response($response)
429 {
430 $this->response_string =& $response;
431
432 // It is a supported format, so just run its formatting method
433 if (array_key_exists($this->format, $this->supported_formats))
434 {
435 return $this->{"_".$this->format}($response);
436 }
437
438 // Find out what format the data was returned in
439 $returned_mime = @$this->_ci->curl->info['content_type'];
440
441 // If they sent through more than just mime, strip it off
442 if (strpos($returned_mime, ';'))
443 {
444 list($returned_mime) = explode(';', $returned_mime);
445 }
446
447 $returned_mime = trim($returned_mime);
448
449 if (array_key_exists($returned_mime, $this->auto_detect_formats))
450 {
451 return $this->{'_'.$this->auto_detect_formats[$returned_mime]}($response);
452 }
453
454 return $response;
455 }
456
457 /**
458 * _xml
459 *
460 * Format XML for output
461 *
462 * @access public
463 * @author Phil Sturgeon
464 * @version 1.0
465 */
466 protected function _xml($string)
467 {
468 return $string ? (array) simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA) : array();
469 }
470
471 /**
472 * _csv
473 *
474 * Format HTML for output. This function is DODGY! Not perfect CSV support but works
475 * with my REST_Controller (https://github.com/philsturgeon/codeigniter-restserver)
476 *
477 * @access public
478 * @author Phil Sturgeon
479 * @version 1.0
480 */
481 protected function _csv($string)
482 {
483 $data = array();
484
485 // Splits
486 $rows = explode("\n", trim($string));
487 $headings = explode(',', array_shift($rows));
488 foreach( $rows as $row )
489 {
490 // The substr removes " from start and end
491 $data_fields = explode('","', trim(substr($row, 1, -1)));
492
493 if (count($data_fields) === count($headings))
494 {
495 $data[] = array_combine($headings, $data_fields);
496 }
497
498 }
499
500 return $data;
501 }
502
503 /**
504 * _json
505 *
506 * Encode as JSON
507 *
508 * @access public
509 * @author Phil Sturgeon
510 * @version 1.0
511 */
512 protected function _json($string)
513 {
514 return json_decode(trim($string));
515 }
516
517 /**
518 * _serialize
519 *
520 * Encode as Serialized array
521 *
522 * @access public
523 * @author Phil Sturgeon
524 * @version 1.0
525 */
526 protected function _serialize($string)
527 {
528 return unserialize(trim($string));
529 }
530
531 /**
532 * _php
533 *
534 * Encode raw PHP
535 *
536 * @access public
537 * @author Phil Sturgeon
538 * @version 1.0
539 */
540 protected function _php($string)
541 {
542 $string = trim($string);
543 $populated = array();
544 eval("\$populated = \"$string\";");
545 return $populated;
546 }
547
548}
549
550/* End of file REST.php */
551/* Location: ./application/libraries/REST.php */