add: api.core.Config (Now config object is an apart singleton) | upd: api.core.Request (uses now the Config singleton)

This commit is contained in:
xdrm-brackets 2017-12-11 18:01:49 +01:00
parent c8c5ff24fb
commit c2f1c9e627
4 changed files with 200 additions and 121 deletions

138
build/api/core/Config.php Normal file
View File

@ -0,0 +1,138 @@
<?php
namespace api\core;
use \error\core\Error;
use \error\core\Err;
class Config{
/* (1) Attributes
---------------------------------------------------------*/
/* (1) Static */
private static $inst = null; // singleton instance
private static function config_path(){ return __ROOT__.'/config/modules.json'; }
public static $allowed_http_methods = [ "GET", "POST", "PUT", "DELETE" ];
/* (2) Instance */
private $raw;
public $index;
public $error;
/* (2) Private constructor
*
* @path<String> Configuration path
*
---------------------------------------------------------*/
private function __construct($path=null){
// Set default error
$this->error = new Error(Err::Success);
/* (1) Access file content
---------------------------------------------------------*/ {
/* (1) Vérification existence fichier config */
if( !file_exists($path) )
return $this->error->set(Err::UnreachableResource);
/* (2) Lecture fichier config */
$conf = @file_get_contents($path);
/* (3) Si erreur lecture */
if( $conf === false )
return $this->error->set(Err::UnreachableResource);
/* (4) Parsage json */
$this->raw = json_decode( $conf, true );
/* (5) Gestion de l'erreur de parsage */
if( $this->raw == null )
return $this->error->set(Err::ParsingFailed, 'json');
}
/* (2) Construction de l'index des chemins
---------------------------------------------------------*/ {
/* (1) Initialisation */
$this->index = [];
$ref = [ '/' => array_merge($this->raw) ];
/* (2) Tant qu'il reste des @ref à traiter */
while( count($ref) > 0 ){
/* (2.1) For each ref */
foreach($ref as $ref_path=>$ref_children){
/* (2.2) For each children */
foreach($ref_children as $path=>$method_or_subpath){
/* (2.2.1) If is an HTTP method -> add to index */
if( in_array($path, self::$allowed_http_methods) ){
/* (2.2.1.1) If no index for this path -> add it */
if( !isset($this->index[$ref_path]) )
$this->index[$ref_path] = [];
/* (2.2.1.2) Add the HTTP method definition */
$this->index[$ref_path][$path] = $method_or_subpath;
/* (2.2.2) If a sub path -> add it to next refs to process */
}else{
if( $ref_path == '/' )
$ref["$ref_path$path"] = $method_or_subpath;
else
$ref["$ref_path/$path"] = $method_or_subpath;
}
}
/* (2.3) In all cases -> remove current from ref */
unset($ref[$ref_path]);
}
}
}
}
/* (3) Static singleton 'get-or-create'
*
* @return inst<Config> Configuration singleton
*
---------------------------------------------------------*/
public static function get(){
/* (1) If @inst already exists -> return singleton */
if( self::$inst instanceof Config )
return self::$inst;
/* (2) If @inst not set -> create singleton and return it */
self::$inst = new self( self::config_path() );
return self::$inst;
}
}

View File

@ -4,6 +4,7 @@
use \database\core\DatabaseDriver;
use \api\core\AuthSystem;
use \api\core\ModuleFactory;
use \api\core\Config;
use \error\core\Error;
use \error\core\Err;
@ -11,18 +12,14 @@
class Request{
// Constantes
public static function config_path(){ return __ROOT__.'/config/modules.json'; }
private static $default_options = [ 'download' => false ];
private static $authsystem = null;
// liste des methodes HTTP autorisées
private static $allowed_http_methods = [ "GET", "POST", "PUT", "DELETE" ];
// Attributs prives utiles (initialisation)
private $id; // chemin extrait de l'URI
private $raw_params; // paramètres reçus
private $params; // paramètres donnés à la fonction
private $schema; // schema configuration
private $options; // options
private $http_method; // methode HTTP appelante
@ -43,7 +40,7 @@
*
---------------------------------------------------------*/
public function __construct($uri=null, $params=null, $forced_method=null){
debug();
return $this->buildRequestObject($uri, $params, $forced_method);
}
@ -72,14 +69,11 @@
/* (2) On met a jour la configuration
/* (2) On vérifie la configuration
---------------------------------------------------------*/
/* (1) Build from configuration */
$this->buildConfig();
/* (2) Dispatch if error */
if( $this->error->get() != Err::Success )
return;
/* (1) Dispatch if error */
if( Config::get()->error->get() != Err::Success )
return ($this->error = Config::get()->error);
/* (3) Verification des types des parametres
@ -155,83 +149,7 @@
/* (3) Construction du schéma à partir de la configuration
*
---------------------------------------------------------*/
private function buildConfig(){
/* (1) Access file content
---------------------------------------------------------*/
/* (1) Vérification existence fichier config */
if( !file_exists(self::config_path()) )
return $this->error->set(Err::UnreachableResource);
/* (2) Lecture fichier config */
$conf = @file_get_contents(self::config_path());
/* (3) Si erreur lecture */
if( $conf === false )
return $this->error->set(Err::UnreachableResource);
/* (4) Parsage json */
$this->schema['raw'] = json_decode( $conf, true );
/* (5) Gestion de l'erreur de parsage */
if( $this->schema['raw'] == null )
return $this->error->set(Err::ParsingFailed, 'json');
/* (2) Construction de l'index des chemins
---------------------------------------------------------*/
/* (1) Initialisation */
$this->schema['index'] = [];
$ref = [ '/' => array_merge($this->schema['raw']) ];
/* (2) Tant qu'il reste des @ref à traiter */
while( count($ref) > 0 ){
/* (2.1) For each ref */
foreach($ref as $ref_path=>$ref_children){
/* (2.2) For each children */
foreach($ref_children as $path=>$method_or_subpath){
/* (2.2.1) If is an HTTP method -> add to index */
if( in_array($path, self::$allowed_http_methods) ){
/* (2.2.1.1) If no index for this path -> add it */
if( !isset($this->schema['index'][$ref_path]) )
$this->schema['index'][$ref_path] = [];
/* (2.2.1.2) Add the HTTP method definition */
$this->schema['index'][$ref_path][$path] = $method_or_subpath;
/* (2.2.2) If a sub path -> add it to next refs to process */
}else{
if( $ref_path == '/' )
$ref["$ref_path$path"] = $method_or_subpath;
else
$ref["$ref_path/$path"] = $method_or_subpath;
}
}
/* (2.3) In all cases -> remove current from ref */
unset($ref[$ref_path]);
}
}
}
/* (4) Verification du format et de la coherence du chemin specifie
/* (3) Verification du format et de la coherence du chemin specifie
*
* @URI<String> URI d'appel (commence par /)
*
@ -253,7 +171,7 @@
$exists_size = 0;
$path = null;
foreach($this->schema['index'] as $key=>$void){
foreach(Config::get()->index as $key=>$void){
$match_size = strlen($key);
/* (1.1) Look for the longer match */
@ -287,11 +205,11 @@
/* (4) Verification de l'existence de la methode (conf)
---------------------------------------------------------*/
/* (1) Check if HTTP method is in allowed methods */
if( !in_array($this->http_method, self::$allowed_http_methods) )
if( !in_array($this->http_method, Config::$allowed_http_methods) )
return $this->error->set(Err::UnknownHttpMethod, $this->http_method);
/* (2) Check if HTTP method is defined for this @path */
if( !isset($this->schema['index'][$path][$this->http_method]) )
if( !isset(Config::get()->index[$path][$this->http_method]) )
return $this->error->set(Err::UnknownMethod, $this->http_method);
@ -308,7 +226,7 @@
/* (5) Retourne si on a la permission d'executer cette methode
/* (4) Retourne si on a la permission d'executer cette methode
*
* @return permission<bool> Retourne si on a les droits ou pas pour executer cette methode
*
@ -318,7 +236,7 @@
/* (1) On recupere les informations utiles
---------------------------------------------------------*/
// On recupere le nom de la methode
$method = $this->schema['index'][$this->id['path']][$this->id['method']];
$method = Config::get()->index[$this->id['path']][$this->id['method']];
// Si aucune permission n'est definie
if( !isset($method['permissions']) || !is_array($method['permissions']) || count($method['permissions']) < 1 )
@ -355,7 +273,7 @@
/* (6) Verification du type des parametres envoyes
/* (5) Verification du type des parametres envoyes
*
* @return correct<bool> Retourne si oui ou non les parametres ont le bon type
*
@ -369,7 +287,7 @@
return $this->error->set(Err::MissingParam);
/* (2) On récupère les données de la méthode */
$method = $this->schema['index'][$this->id['path']][$this->id['method']];
$method = Config::get()->index[$this->id['path']][$this->id['method']];
/* (3) Si pas 'parameters' dans la config */
if( !isset($method['parameters']) || !is_array($method['parameters']) )
@ -446,7 +364,7 @@
/* (7) Ajout des options a partir de la configuration
/* (6) Ajout des options a partir de la configuration
*
* @return correct<bool> Retourne FAUS en cas d'erreur
*
@ -455,7 +373,7 @@
/* (1) On récupère les options de la méthode en cours
---------------------------------------------------------*/
$method = $this->schema['index'][$this->id['path']][$this->id['method']];
$method = Config::get()->index[$this->id['path']][$this->id['method']];
/* (1) Si 'option' n'est pas défini (ou incorrect), on met les valeurs par défaut */
if( !isset($method['options']) || !is_array($method['options']) )
@ -491,7 +409,7 @@
/* (8) Execute le traitement associe et remplie la reponse
/* (7) Execute le traitement associe et remplie la reponse
*
* @return answer<Response> Retourne une reponse de type <Response> si tout s'est bien passe
*
@ -550,7 +468,7 @@
/* EXECUTE LE TRAITEMENT ASSOCIE ET RENVOIE UN FICHIER AVEC LE HEADER ET LE BODY SPECIFIE
/* (8) Gestion d'un téléchargement HTTP
*
*/
public function download(){

20
build/api/module/root.php Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace api\module;
use \error\core\Error;
class root{
/* Generates the API documentation
*
*/
public function get($args){
extract($args);
return [ 'bla' => uniqid() ];
}
}

View File

@ -1,6 +1,6 @@
{
"GET": {
"description": "GET /.",
"description": "Returns the API documentation",
"permissions": [],
"parameters": {}
},
@ -60,28 +60,8 @@
},
"a": {
"GET": {
"description": "GET A.",
"permissions": [],
"parameters": {}
},
"POST": {
"description": "POST A.",
"permissions": [],
"parameters": {}
},
"b": {
"PUT": {
"description": "PUT A/B.",
"permissions": [],
"parameters": {}
},
"DELETE": {
"description": "DELETE A/B.",
"permissions": [],
"parameters": {}
},
"c": {
"PUT": {
@ -95,7 +75,30 @@
"parameters": {}
}
},
"PUT": {
"description": "PUT A/B.",
"permissions": [],
"parameters": {}
},
"DELETE": {
"description": "DELETE A/B.",
"permissions": [],
"parameters": {}
}
},
"GET": {
"description": "GET A.",
"permissions": [],
"parameters": {}
},
"POST": {
"description": "POST A.",
"permissions": [],
"parameters": {}
}
}
}