123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- <?php
- /**
- * Classe de gestion des API (REST).
- * @author Valentin CARRUESCO
- * @category Plugin
- * @license copyright
- */
- class Api{
- public $slug,$description;
- function __construct($slug=null,$description=null){
- if(isset($slug)) $this->slug = $slug;
- if(isset($description)) $this->description = $description;
- $this->route = array();
- return $this;
- }
- function route($slug = null,$description = null,$method = null,$callback){
- $route = new ApiRoute($slug,$description,$method,$callback);
- $this->route[$route->slug][$method] = $route;
- }
- function register(){
- Plugin::addHook('api',function(&$apis){
- $apis[$this->slug] = $this;
-
- });
- }
- public static function run(){
- global $_,$myUser;
- $response = array();
- try{
- /*set_error_handler(function( $errno , $errstr , $errfile , $errline){
- throw new Exception("Error ".$errno." Processing Request ".$errfile.$errstr, 500);
- });
- register_shutdown_function(function( $errno , $errstr , $errfile , $errline){
- $error = error_get_last();
- throw new Exception("Error ".E_CORE_ERROR." Processing Request ".$error['file'], 500);
- });*/
- $command = explode('/',$_['command']);
- if(count($command)<1) throw new Exception("Unspecified API");
- $headers = apache_request_headers();
-
- //basic auth
- if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])){
- $user = User::check($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
- if(!$user) throw new Exception('Le compte spécifié est inexistant');
- $myUser = $user;
- }
- $request = array(
- 'version' =>array_shift($command),
- 'module' =>array_shift($command),
- 'route' =>array_shift($command),
- 'body' =>file_get_contents("php://input"),
- 'method' => strtoupper($_SERVER['REQUEST_METHOD']),
- 'parameters' => $_,
- 'pathes' => array_filter($command)
- );
-
- $code = 200;
- $headers = array(
- 'Content-Type: application/json'
- );
- $apis = array();
- Plugin::callHook('api',array(&$apis));
-
- if(!isset($request['version']) || !is_numeric($request['version'])) throw new Exception("Api version is missing or invalid, specify ".ROOT_URL."/api/{version} for valid requests", 404);
- if($request['module'] == 'schema'){
- foreach ($apis as $api) {
- $routes= array();
- foreach($api->route as $route){
-
- foreach($route as $method=>$infos){
- if(!isset($routes[$infos->slug])) $routes[$infos->slug] = array() ;
- $routes[$infos->slug][] = $infos->method.' '.$api->slug .'/'.$infos->pattern .': '. $infos->description ;
- }
- }
- $response[] = array( $api->slug => $api->description,'routes'=> $routes);
- }
- }else{
- if(!isset($apis[$request['module']])) throw new Exception("Api '".$request['module']."' is missing, see ".ROOT_URL."/api/schema for available calls", 404);
- $api = $apis[$request['module']];
-
-
- if(!isset($api->route[$request['route']])) throw new Exception("Route '".$api->slug.'/'.$request['route']."' is missing, see ".ROOT_URL."/api/schema?pretty for available calls", 404);
- $route = $api->route[$request['route']];
-
- if(!isset($route[$request['method']])) throw new Exception("Method ".$request['method']." '".$api->slug.'/'.$route->slug."' is not allowed", 405);
- $method = $route[$request['method']];
- $callback = $method->callback;
-
- $callback($request,$response);
- if(isset($response['code'])) $code = $response['code'];
- if(isset($response['headers'])) $headers = array_merge($headers,$response['headers']);
- unset($response['code']);
- unset($response['headers']);
- }
-
- }catch(Exception $e){
- $response['error'] = $e->getMessage();
- $code = $e->getCode();
- if(empty($code) || $code==0) $code = 666;
- }
- $codes = array(
- 200 => 'HTTP/1.1 200 Ok',
- 201 => 'HTTP/1.1 201 Created',
- 204 => 'HTTP/1.1 204 No Content',
- 207 => 'HTTP/1.1 207 Multi-Status',
- 400 => 'HTTP/1.0 400 Bad Request',
- 401 => 'HTTP/1.0 401 Unauthorized',
- 403 => 'HTTP/1.1 403 Forbidden',
- 404 => 'HTTP/1.1 404 Not Found',
- 404 => 'HTTP/1.1 405 Method Not Allowed',
- 406 => 'HTTP/1.1 406 Not acceptable',
- 409 => 'HTTP/1.1 409 Conflict',
- 415 => 'HTTP/1.1 415 Unsupported Media Type',
- 423 => 'HTTP/1.1 423 Locked',
- 500 => 'HTTP/1.1 500 Internal Server Error',
- 501 => 'HTTP/1.1 501 Not implemented',
- 666 => 'HTTP/1.1 666 Welcome to Hell mate!',
- );
- if (ob_get_length()) ob_end_clean();
- header(isset($codes[$code]) ? $codes[$code] : $codes[666]);
-
- foreach ($headers as $header) {
- header($header);
- }
-
- if(isset($_['pretty'])){
- echo json_encode($response,JSON_PRETTY_PRINT);
- }else{
- echo json_encode($response);
- }
- exit();
- }
- }
- class ApiRoute{
- public $slug,$description,$callback,$method,$pathes,$parameters,$pattern;
- function __construct($slug='default',$description='No description',$method='GET',$callback){
- $this->pattern = $slug;
- $infos = explode('?',$slug);
- if(isset($infos[1])) $this->parameters = $infos[1];
- $infos = explode('/',$infos[0]);
- $this->slug = array_shift($infos);
- $this->pathes = $infos;
- $this->description = $description;
- $this->method = $method;
- $this->callback = $callback;
- }
- }
- ?>
|