From c8c5ff24fb60fe8455f29af96c91ccb2a2b0d195 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 11 Dec 2017 12:15:05 +0100 Subject: [PATCH] upd: api.core (Made configuration recursive for path) --- build/api/core/ModuleFactory.php | 17 ++++--- build/api/core/Request.php | 85 ++++++++++++++++++++------------ config/modules.json | 57 ++++++++++++++++----- 3 files changed, 109 insertions(+), 50 deletions(-) diff --git a/build/api/core/ModuleFactory.php b/build/api/core/ModuleFactory.php index 1c9109d..23ab7e5 100755 --- a/build/api/core/ModuleFactory.php +++ b/build/api/core/ModuleFactory.php @@ -27,18 +27,21 @@ /* (1) On gère les arguments */ $arguments = is_array($arguments) ? $arguments : []; - /* (2) On transforme @module en namespace */ + /* (2) Exception: URI Racine */ + if( $module == '/' ) + $module = '/root'; + + /* (3) On transforme @module en namespace */ $module_ns = str_replace('/', '\\', $module); - - /* (1) On vérifie que la classe existe */ - if( !file_exists(__BUILD__."/api/module/$module.php") ) + /* (4) On vérifie que la classe existe */ + if( !file_exists(__BUILD__."/api/module$module.php") ) return false; - /* (2) On récupère la classe */ - $class_name = "\\api\\module\\$module_ns"; + /* (5) On récupère la classe */ + $class_name = "\\api\\module$module_ns"; - /* (3) On retourne une instance */ + /* (6) On retourne une instance */ return new $class_name($arguments); } diff --git a/build/api/core/Request.php b/build/api/core/Request.php index aa59a82..e4ae671 100755 --- a/build/api/core/Request.php +++ b/build/api/core/Request.php @@ -19,7 +19,7 @@ // Attributs prives utiles (initialisation) - private $path; // chemin de base (uri) + 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 @@ -67,10 +67,11 @@ $this->error = new Error(Err::Success); /* (2) Si pas parametre manquant, on quitte */ - if( $uri == null ) + if( is_null($uri) ) return $this->error->set(Err::MissingPath); + /* (2) On met a jour la configuration ---------------------------------------------------------*/ /* (1) Build from configuration */ @@ -87,10 +88,14 @@ if( !is_string($uri) ) // Si le type est incorrect return $this->error->set(Err::WrongPathModule); - /* (2) Formattage @params en tableau */ + /* (2) Add slash at the beginning of URI */ + if( !preg_match('@^\/@', $uri) ) + $uri = "/$uri"; + + /* (3) Formattage @params en tableau */ $this->raw_params = (is_array($params)) ? $params : []; - /* (3) On définit en constante la méthode HTTP */ + /* (4) On définit en constante la méthode HTTP */ if( !isset($_SERVER['REQUEST_METHOD']) && !is_string($forced_method) ) return $this->error->set(Err::UnknownHttpMethod); @@ -176,29 +181,47 @@ return $this->error->set(Err::ParsingFailed, 'json'); - /* (2) Construction des outils d'accès + /* (2) Construction de l'index des chemins ---------------------------------------------------------*/ /* (1) Initialisation */ $this->schema['index'] = []; + $ref = [ '/' => array_merge($this->schema['raw']) ]; - /* (2) Pour chaque chemin */ - foreach($this->schema['raw'] as $path=>$methods){ - /* (2.1) Pour chaque méthode */ - foreach($methods as $method=>$data){ + /* (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.1.1) Suppression si pas dans les méthodes autorisées */ - if( !in_array($method, self::$allowed_http_methods) ){ - unset($this->schema[$path][$method]); - continue; } - /* (2.1.2) Création de l'index pour le chemin si n'existe pas déja */ - if( !isset($this->schema['index'][$path]) ) - $this->schema['index'][$path] = []; - - /* (2.1.3) Ajout de la méthode à l'index */ - $this->schema['index'][$path][] = $method; + /* (2.3) In all cases -> remove current from ref */ + unset($ref[$ref_path]); } @@ -210,7 +233,7 @@ /* (4) Verification du format et de la coherence du chemin specifie * - * @path String correspondant au chemin de delegation ("module/methode") + * @URI URI d'appel (commence par /) * * @return validity Retourne si oui ou non l'objet est correct * @@ -220,7 +243,7 @@ /* (1) Verification format general ---------------------------------------------------------*/ /* (1) If wrong format -> exit */ - if( !preg_match('@^[\w-]+(\/[\w-]+)*\/?$@', $uri, $matches) ) + if( !preg_match('@^\/[\w-]+(\/[\w-]+)*\/?$@', $uri, $matches) && $uri != '/' ) return $this->error->set(Err::WrongPathModule); @@ -268,14 +291,14 @@ return $this->error->set(Err::UnknownHttpMethod, $this->http_method); /* (2) Check if HTTP method is defined for this @path */ - if( !in_array($this->http_method, $this->schema['index'][$path]) ) + if( !isset($this->schema['index'][$path][$this->http_method]) ) return $this->error->set(Err::UnknownMethod, $this->http_method); /* (5) Enregistrement du chemin et renvoi de SUCCESS ---------------------------------------------------------*/ - $this->path = [ + $this->id = [ 'path'=> $path, 'method'=> $this->http_method ]; @@ -295,7 +318,7 @@ /* (1) On recupere les informations utiles ---------------------------------------------------------*/ // On recupere le nom de la methode - $method = $this->schema['raw'][$this->path['path']][$this->path['method']]; + $method = $this->schema['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 ) @@ -346,7 +369,7 @@ return $this->error->set(Err::MissingParam); /* (2) On récupère les données de la méthode */ - $method = $this->schema['raw'][$this->path['path']][$this->path['method']]; + $method = $this->schema['index'][$this->id['path']][$this->id['method']]; /* (3) Si pas 'parameters' dans la config */ if( !isset($method['parameters']) || !is_array($method['parameters']) ) @@ -432,7 +455,7 @@ /* (1) On récupère les options de la méthode en cours ---------------------------------------------------------*/ - $method = $this->schema['raw'][$this->path['path']][$this->path['method']]; + $method = $this->schema['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']) ) @@ -483,18 +506,18 @@ /* (2) On essaie d'instancier le module ---------------------------------------------------------*/ - $instance = ModuleFactory::getModule($this->path['path']); + $instance = ModuleFactory::getModule($this->id['path']); if( $instance instanceof Error ){ - $this->error->set(Err::UncallableModule, $this->path['path']); + $this->error->set(Err::UncallableModule, $this->id['path']); return new Response($this->error); } /* (3) On verifie que la methode est amorcable ---------------------------------------------------------*/ - if( !is_callable([$instance, $this->path['method']]) ){ - $this->error->set(Err::UncallableMethod, $this->path['method']); + if( !is_callable([$instance, $this->id['method']]) ){ + $this->error->set(Err::UncallableMethod, $this->id['method']); return new Response($this->error); } @@ -502,7 +525,7 @@ /* (4) On amorce la methode ---------------------------------------------------------*/ /* (1) On lance la fonction */ - $returned = call_user_func( [$instance, $this->path['method']], $this->params ); + $returned = call_user_func( [$instance, $this->id['method']], $this->params ); /* (2) On appelle le destructeur (si défini) */ $instance = null; diff --git a/config/modules.json b/config/modules.json index 473798e..40926c6 100755 --- a/config/modules.json +++ b/config/modules.json @@ -1,4 +1,9 @@ { + "GET": { + "description": "GET /.", + "permissions": [], + "parameters": {} + }, "admin": { @@ -40,18 +45,6 @@ }, - - "token/renew": { - "POST": { - "description": "Renewal of the cyclic hashing system.", - "permission": ["cyclic-hash"], - "parameters": { - "hash": { "description": "new hash to store.", "type": "hash" } - } - } - }, - - "release": { "GET": { @@ -64,5 +57,45 @@ } } + }, + + "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": { + "description": "PUT A/B/C.", + "permissions": [], + "parameters": {} + }, + "DELETE": { + "description": "DELETE A/B/C.", + "permissions": [], + "parameters": {} + } + + } + } } }