API.class.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. abstract class API {
  3. /**
  4. * Property: method
  5. * The HTTP method this request was made in, either GET, POST, PUT or DELETE
  6. */
  7. protected $method = '';
  8. /**
  9. * Property: endpoint
  10. * The Model requested in the URI. eg: /files
  11. */
  12. protected $endpoint = '';
  13. /**
  14. * Property: verb
  15. * An optional additional descriptor about the endpoint, used for things that can
  16. * not be handled by the basic methods. eg: /files/process
  17. */
  18. protected $verb = '';
  19. /**
  20. * Property: args
  21. * Any additional URI components after the endpoint and verb have been removed, in our
  22. * case, an integer ID for the resource. eg: /<endpoint>/<verb>/<arg0>/<arg1>
  23. * or /<endpoint>/<arg0>
  24. */
  25. protected $args = Array();
  26. /**
  27. * Property: file
  28. * Stores the input of the PUT request
  29. */
  30. protected $file = Null;
  31. /**
  32. * Constructor: __construct
  33. * Allow for CORS, assemble and pre-process the data
  34. */
  35. public function __construct($request) {
  36. $this->args = explode('/', rtrim($request, '/'));
  37. $this->endpoint = array_shift($this->args);
  38. if (array_key_exists(0, $this->args) && !is_numeric($this->args[0])) {
  39. $this->verb = array_shift($this->args);
  40. }
  41. $this->method = $_SERVER['REQUEST_METHOD'];
  42. if ($this->method == 'POST' && array_key_exists('HTTP_X_HTTP_METHOD', $_SERVER)) {
  43. if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'DELETE') {
  44. $this->method = 'DELETE';
  45. }
  46. else if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'PUT') {
  47. $this->method = 'PUT';
  48. }
  49. else {
  50. throw new Exception("Unexpected header");
  51. }
  52. }
  53. switch($this->method) {
  54. // @TODO: 200 only if authorization header present?
  55. // Preflight request
  56. case 'OPTIONS':
  57. $this->request = array();
  58. $this->_response('Got it', 200);
  59. break;
  60. // Delete
  61. case 'DELETE':
  62. $this->request = $this->_cleanInputs($_GET);
  63. break;
  64. // Create
  65. case 'POST':
  66. $this->request = $this->_cleanInputs($_POST);
  67. break;
  68. // Read
  69. case 'GET':
  70. $this->request = $this->_cleanInputs($_GET);
  71. break;
  72. // Update
  73. case 'PUT':
  74. $this->request = $this->_cleanInputs($_GET);
  75. $this->file = file_get_contents("php://input");
  76. break;
  77. default:
  78. $this->_response('Invalid method', 405);
  79. break;
  80. }
  81. }
  82. public function process() {
  83. if (method_exists($this, $this->endpoint)) {
  84. try {
  85. $this->log($this->args, $this->verb);
  86. return $this->_response($this->{$this->endpoint}($this->args, $this->verb));
  87. }
  88. catch (Exception $e) {
  89. return $this->_response($e->getMessage(), 405);
  90. }
  91. }
  92. return $this->_response("No endpoint: $this->endpoint", 404);
  93. }
  94. private function _response($data, $status = 200) {
  95. header("HTTP/1.1 " . $status . " " . $this->_requestStatus($status));
  96. return json_encode($data);
  97. }
  98. private function _cleanInputs($data) {
  99. $clean_input = Array();
  100. if (is_array($data)) {
  101. foreach ($data as $k => $v) {
  102. $clean_input[$k] = $this->_cleanInputs($v);
  103. }
  104. }
  105. else {
  106. $clean_input = trim($data);//trim(strip_tags($data));
  107. }
  108. return $clean_input;
  109. }
  110. private function _requestStatus($code) {
  111. $status = array(
  112. 200 => 'OK',
  113. 404 => 'Not Found',
  114. 405 => 'Method Not Allowed',
  115. 500 => 'Internal Server Error',
  116. );
  117. return ($status[$code])?$status[$code]:$status[500];
  118. }
  119. }
  120. ?>