api de gestion de ticket, basé sur php-crud-api. Le but est de décorrélé les outils de gestion des données, afin
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.php 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. include "config.php";
  3. function connectDatabase($hostname,$username,$password,$database) {
  4. global $config;
  5. $mysqli = new mysqli($hostname,$username,$password,$database);
  6. if ($mysqli->connect_errno) {
  7. die('Connect failed: '.$mysqli->connect_error);
  8. }
  9. return $mysqli;
  10. }
  11. function parseGetParameter($name,$characters,$default) {
  12. $value = isset($_GET[$name])?$_GET[$name]:$default;
  13. return $characters?preg_replace("/[^$characters]/",'',$value):$value;
  14. }
  15. function applyWhitelist($table,$action,$list) {
  16. if ($list===false) return $table;
  17. $list = array_filter($list, function($actions){
  18. return strpos($actions,$action[0])!==false;
  19. });
  20. return array_intersect($table, array_keys($list));
  21. }
  22. function applyBlacklist($table,$action,$list) {
  23. if ($list===false) return $table;
  24. $list = array_filter($list, function($actions) use ($action) {
  25. return strpos($actions,$action[0])!==false;
  26. });
  27. return array_diff($table, array_keys($list));
  28. }
  29. function applyWhitelistAndBlacklist($table, $action, $whitelist, $blacklist) {
  30. $table = applyWhitelist($table, $action, $whitelist);
  31. $table = applyBlacklist($table, $action, $blacklist);
  32. if (empty($table)) exitWith404();
  33. return $table;
  34. }
  35. function processTableParameter($table,$database,$mysqli) {
  36. global $config;
  37. $tablelist = explode(',',$table);
  38. $tables = array();
  39. foreach ($tablelist as $table) {
  40. $table = str_replace('*','%',$table);
  41. if ($result = $mysqli->query("SELECT `TABLE_NAME` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_NAME` LIKE '$table' AND `TABLE_SCHEMA` = '$database'")) {
  42. while ($row = $result->fetch_row()) $tables[] = $row[0];
  43. $result->close();
  44. }
  45. }
  46. return $tables;
  47. }
  48. function findPrimaryKey($table,$database,$mysqli) {
  49. global $config;
  50. $keys = array();
  51. if ($result = $mysqli->query("SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `COLUMN_KEY` = 'PRI' AND `TABLE_NAME` = '$table[0]' AND `TABLE_SCHEMA` = '$database'")) {
  52. while ($row = $result->fetch_row()) $keys[] = $row[0];
  53. $result->close();
  54. }
  55. return count($keys)?$keys[0]:false;
  56. }
  57. function exitWith404() {
  58. die(header("Content-Type:",true,404));
  59. }
  60. function startOutput($callback) {
  61. if ($callback) {
  62. header("Content-Type: application/javascript");
  63. echo $callback.'(';
  64. } else {
  65. header("Content-Type: application/json");
  66. }
  67. }
  68. function endOutput($callback) {
  69. if ($callback) {
  70. echo ');';
  71. }
  72. }
  73. function processKeyParameter($key,$table,$database,$mysqli) {
  74. if ($key) {
  75. $key = array($key,findPrimaryKey($table,$database,$mysqli));
  76. if ($key[1]===false) exitWith404();
  77. }
  78. return $key;
  79. }
  80. function processFilterParameter($filter,$match,$mysqli) {
  81. if ($filter) {
  82. $filter = explode(':',$filter,2);
  83. if (count($filter)==2) {
  84. $filter[0] = preg_replace('/[^a-zA-Z0-9\-_]/','',$filter[0]);
  85. if ($match=='in') {
  86. $filter[1] = implode("','",array_map(function($v){ return preg_replace('/[^a-zA-Z0-9\-]/','',$v); },explode(',',$filter[1])));
  87. } else {
  88. $filter[1] = $mysqli->real_escape_string($filter[1]);
  89. }
  90. $filter[2] = 'LIKE';
  91. if ($match=='any'||$match=='start') $filter[1] .= '%';
  92. if ($match=='any'||$match=='end') $filter[1] = '%'.$filter[1];
  93. if ($match=='exact') $filter[2] = '=';
  94. if ($match=='lower') $filter[2] = '<';
  95. if ($match=='upto') $filter[2] = '<=';
  96. if ($match=='from') $filter[2] = '>=';
  97. if ($match=='higher') $filter[2] = '>';
  98. if ($match=='in') $filter[2] = 'IN';
  99. $filter[1]="'$filter[1]'";
  100. if ($filter[2]=='IN') $filter[1]="($filter[1])";
  101. } else {
  102. $filter = false;
  103. }
  104. }
  105. return $filter;
  106. }
  107. function processPageParameter($page) {
  108. if ($page) {
  109. $page = explode(',',$page,2);
  110. if (count($page)<2) $page[1]=20;
  111. $page[0] = ($page[0]-1)*$page[1];
  112. }
  113. return $page;
  114. }
  115. function retrieveObject($key,$table,$mysqli) {
  116. if (!$key) return false;
  117. if ($result = $mysqli->query("SELECT * FROM `$table[0]` WHERE `$key[1]` = '$key[0]'")) {
  118. $object = $result->fetch_assoc();
  119. $result->close();
  120. }
  121. return $object;
  122. }
  123. function createObject($input,$table,$mysqli) {
  124. if (!$input) return false;
  125. $keys = implode('`,`',array_map(function($v){ return preg_replace('/[^a-zA-Z0-9\-_]/','',$v); },array_keys((array)$input)));
  126. $values = implode("','",array_map(function($v) use ($mysqli){ return $mysqli->real_escape_string($v); },array_values((array)$input)));
  127. $mysqli->query("INSERT INTO `$table[0]` (`$keys`) VALUES ('$values')");
  128. return $mysqli->insert_id;
  129. }
  130. function updateObject($key,$input,$table,$mysqli) {
  131. if (!$input) return false;
  132. $sql = "UPDATE `$table[0]` SET ";
  133. foreach (array_keys((array)$input) as $i=>$k) {
  134. if ($i) $sql .= ",";
  135. $v = $input->$k;
  136. $sql .= "`$k`='$v'";
  137. }
  138. $sql .= " WHERE `$key[1]`='$key[0]'";
  139. $mysqli->query($sql);
  140. return $mysqli->affected_rows;
  141. }
  142. function deleteObject($key,$table,$mysqli) {
  143. $mysqli->query("DELETE FROM `$table[0]` WHERE `$key[1]`='$key[0]'");
  144. return $mysqli->affected_rows;
  145. }
  146. $action = parseGetParameter('action', 'a-z', 'list');
  147. $table = parseGetParameter('table', 'a-zA-Z0-9\-_*,', '*');
  148. $key = parseGetParameter('key', 'a-zA-Z0-9\-,', false); // auto-increment or uuid
  149. $callback = parseGetParameter('callback', 'a-zA-Z0-9\-_', false);
  150. $page = parseGetParameter('page', '0-9,', false);
  151. $filter = parseGetParameter('filter', false, 'start');
  152. $match = parseGetParameter('match', 'a-z', false);
  153. $mysqli = connectDatabase($config["hostname"], $config["username"], $config["password"], $config["database"]);
  154. $table = processTableParameter($table,$config["database"],$mysqli);
  155. $key = processKeyParameter($key,$table,$config["database"],$mysqli);
  156. $filter = processFilterParameter($filter,$match,$mysqli);
  157. $page = processPageParameter($page);
  158. $table = applyWhitelistAndBlacklist($table,$action,$config['whitelist'],$config['blacklist']);
  159. $object = retrieveObject($key,$table,$mysqli);
  160. $input = json_decode(file_get_contents('php://input'));
  161. switch($action){
  162. case 'list':
  163. startOutput($callback);
  164. echo '{';
  165. $tables = $table;
  166. foreach ($tables as $t=>$table) {
  167. $count = false;
  168. if ($t>0) echo ',';
  169. echo '"'.$table.'":{';
  170. if ($t==0 && is_array($page)) {
  171. $sql = "SELECT COUNT(*) FROM `$table`";
  172. if (is_array($filter)) $sql .= " WHERE `$filter[0]` $filter[2] $filter[1]";
  173. if ($result = $mysqli->query($sql)) {
  174. $pages = $result->fetch_row();
  175. $count = $pages[0];
  176. }
  177. }
  178. echo '"columns":';
  179. $sql = "SELECT * FROM `$table`";
  180. if ($t==0 && is_array($filter)) $sql .= " WHERE `$filter[0]` $filter[2] $filter[1]";
  181. if ($t==0 && is_array($page)) $sql .= " LIMIT $page[1] OFFSET $page[0]";
  182. if ($result = $mysqli->query($sql)) {
  183. $fields = array();
  184. foreach ($result->fetch_fields() as $field) $fields[] = $field->name;
  185. echo json_encode($fields);
  186. echo ',"records":[';
  187. $first_row = true;
  188. while ($row = $result->fetch_row()) {
  189. if ($first_row) $first_row = false;
  190. else echo ',';
  191. echo json_encode($row);
  192. }
  193. $result->close();
  194. }
  195. if ($results) echo ',"results":'.$count;
  196. echo ']}';
  197. }
  198. echo '}';
  199. endOutput($callback);
  200. break;
  201. case 'read':
  202. if (!$object) exitWith404();
  203. startOutput($callback);
  204. echo json_encode($object);
  205. endOutput($callback);
  206. break;
  207. case 'create':;
  208. if (!$input) exitWith404();
  209. startOutput($callback);
  210. echo json_encode(createObject($input,$table,$mysqli));
  211. endOutput($callback);
  212. break;
  213. case 'update':
  214. if (!$input) exitWith404();
  215. startOutput($callback);
  216. echo json_encode(updateObject($key,$input,$table,$mysqli));
  217. endOutput($callback);
  218. break;
  219. case 'delete':
  220. if (!$object) exitWith404();
  221. startOutput($callback);
  222. echo json_encode(deleteObject($key,$table,$mysqli));
  223. endOutput($callback);
  224. break;
  225. default: exitWith404();
  226. }