Building project's base

Inherited from NxTIC
This commit is contained in:
xdrm-brackets 2016-11-06 17:04:17 +01:00
parent 69c7aca00f
commit 2b26db7d30
15 changed files with 1214 additions and 0 deletions

2
.htaccess Normal file
View File

@ -0,0 +1,2 @@
RewriteEngine on
RewriteRule ^(.*)$ public_html/$1 [QSA,L]

2
build/.htaccess Normal file
View File

@ -0,0 +1,2 @@
Order deny,allow
Deny from all

17
build/Builder.php Normal file
View File

@ -0,0 +1,17 @@
<?php
/**************************
* Builder *
* 05-11-16 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
class Builder{
}

146
build/api/core/Checker.php Normal file
View File

@ -0,0 +1,146 @@
<?php
namespace api\core;
class Checker{
/* VERIFICATIONS DES TYPES UTILES GENERIQUES
*
* @type<String> Type que l'on veut verifier
* @value<mixed*> Valeur a verifier
*
* @return match<Boolean> Retourne si oui ou non la valeur @value est du bon type @type
*
*/
public static function run($type, $value){
$checker = true;
/* [0] On verifie que $value n'est pas nul
=========================================================*/
if( is_null($value) ) return false;
/* [1] Si de type VARCHAR(min, max, flags)
=========================================================*/
if( preg_match('/^varchar\((\d+), ?(\d+)((?:, ?\w+)+)?\)$/', $type, $match) ){
// On recupere la taille min
$min = (int) $match[1];
// On recupere la taille max
$max = (int) $match[2];
// On recupere le sous-type si défini
$flags = isset($match[3]) ? explode(',', substr($match[3], 1)) : null;
// On effectue la verification de taille
$lenCheck = $checker && is_string($value) && strlen($value) <= $max && strlen($value) >= $min;
// On vérifie les FLAGS s'il est donné
if( is_array($flags) )
foreach( $flags as $flag )
$lenCheck = $lenCheck && self::run($flag, $value);
return $lenCheck;
}
/* [2] Si de type ARRAY(type_elements)
=========================================================*/
if( preg_match('/^array<(.+)>$/', $type, $match) ){
// Si c'est pas un tableau on retourne une erreur
if( !is_array($value) )
return false;
$elements_type = $match[1];
// On verifie le type pour chaque element
foreach($value as $element)
// Si erreur dans au moins 1 element, on retourne que c'est incorrect
if( !self::run($elements_type, ($element) ) )
return false;
// Si aucune erreur, on retourne que tout est bon
return true;
}
/* [n] Sinon, tous les autres types definis
=========================================================*/
switch($type){
// Quoi que ce soit
case 'mixed':
return $checker && !is_null($value);
break;
// Entier positif (id dans BDD)
case 'id':
return $checker && is_numeric($value) && $value <= 2147483647 && $value >= 0;
break;
// Code RFID
case 'rfid':
return $checker && is_string($value) && preg_match('/^[\dA-F]{2}(\-[\dA-F]{2}){3,5}$/i', $value);
break;
// String quelconque (peut etre vide)
case 'text':
return $checker && is_string($value);
// Adresse mail (255 caracteres max)
case 'mail':
return $checker && is_string($value) && strlen($value) <= 50 && preg_match('/^[\w\.-]+@[\w\.-]+\.[a-z]{2,4}$/i', $value);
break;
// Hash sha1/md5
case 'hash':
return $checker && is_string($value) && preg_match('/^[\da-f]+$/i', $value) && (strlen($value) == 40 || strlen($value) == 64);
break;
case 'alphanumeric':
return $checker && is_string($value) && preg_match('/^[\w\.-]+$/ui', $value);
break;
case 'letters':
return $checker && is_string($value) && preg_match('/^[a-z -]+$/i', $value);
break;
case 'status':
return $checker && is_numeric($value) && floor($value) == $value && $value >= 0 && $value <= 100;
break;
// Tableau non vide
case 'array':
return $checker && is_array($value) && count($value) > 0;
break;
// Boolean
case 'boolean':
return $checker && is_bool($value);
break;
// Objet non vide
case 'object':
return $checker && is_object($value) && count((array) $value) > 0;
break;
// Chaine JSON (on vérifie via le parser)
case 'json':
return $checker && is_string($value) && json_decode($value, true) !== NULL;
break;
default:
return false;
break;
}
return $checker;
}
}
?>

View File

@ -0,0 +1,530 @@
<?php
namespace api\core;
use \database\core\DatabaseDriver;
use \manager\ManagerError;
use \api\core\Checker;
class ModuleRequest{
// Constantes
public static function config_path(){ return __CONFIG__.'/modules.json'; }
public static $default_options = [
'download' => false
];
// Attributs prives utiles (initialisation)
private $path;
private $params;
private $modules;
private $options;
// Contiendra la reponse a la requete
public $answer;
// Contiendra l'etat de la requete
public $error;
/* CONSTRUCTEUR D'UNE REQUETE DE MODULE
*
* @path<String> Chemin de delegation ("module/methode")
* @param<Array> Tableau associatif contenant les parametres utiles au traitement
* @token<String> Token d'acces a l'api (OPTIONNEL)
*
* @return status<Boolean> Retourne si oui ou non tout s'est bien passe
*
*/
public function __construct($path=null, $params=null, $token=null){
// Si pas parametre manquant, on quitte
if( $path == null ){
$this->error = ManagerError::MissingPath;
return false;
}
/* [0] On met a jour la configuration
=========================================================*/
// Modules specifies
$this->modules = json_decode( file_get_contents(self::config_path()), true );
// Gestion de l'erreur de parsage
if( $this->modules == null ){
$this->error = ManagerError::ParsingFailed;
return false;
}
/* [1] Verification des types des parametres
=========================================================*/
// Type de @path
if( !is_string($path) ){ // Si le type est incorrect
$this->error = ManagerError::WrongPathModule;
return false; // On retourne FALSE, si erreur
}
// Type de @data (optionnel)
$params = (is_array($params)) ? $params : [];
/* [2] Verification du chemin (existence module+methode)
=========================================================*/
if( !$this->checkPath($path) ) // Verification de la coherence du chemin + attribution
return false;
/* [3] Verification des droits
=========================================================*/
if( !$this->checkPermission($token) ) // Si on a pas les droits
return false;
/* [4] Verification des parametres (si @type est defini)
=========================================================*/
if( !$this->checkParams($params) ){ // Verification de tous les types
$this->error = ManagerError::ParamError;
return false;
}
/* [5] Récupèration des options
=========================================================*/
$this->buildOptions();
/* [6] Construction de l'objet
=========================================================*/
$this->params = $params;
$this->error = ManagerError::Success;
return true; // On retourne que tout s'est bien passe
}
/* EXECUTE LE TRAITEMENT ASSOCIE ET REMPLIE LA REPONSE
*
* @return answer<ModuleResponse> Retourne une reponse de type <ModuleResponse> si tout s'est bien passe
*
*/
public function dispatch(){
/* [0] Si c'est un download, on lance la methode `download()`
=========================================================*/
if( $this->options['download'] === true )
return $this->download();
/* [1] On verifie qu'aucune erreur n'a ete signalee
=========================================================*/
if( $this->error != ManagerError::Success ) // si il y a une erreur
return new ModuleResponse($this->error); // on la passe a la reponse
/* [2] On verifie que la methode est amorcable
=========================================================*/
if( !is_callable($this->getFunctionCaller()) ){
$this->error = ManagerError::UncallableMethod;
return new ModuleResponse($this->error);
}
/* [3] On amorce la methode
=========================================================*/
$returned = call_user_func( $this->getFunctionCaller(), $this->params );
/* [4] Gestion de la reponse
=========================================================*/
$response = new ModuleResponse($this->error);
$response->appendAll($returned);
return $response;
}
/* EXECUTE LE TRAITEMENT ASSOCIE ET RENVOIE UN FICHIER AVEC LE HEADER ET LE BODY SPECIFIE
*
*/
public function download(){
/* [1] On verifie qu'aucune erreur n'a ete signalee
=========================================================*/
if( $this->error != ManagerError::Success ) // si il y a une erreur
return new ModuleResponse($this->error); // on la passe a la reponse
/* [2] On verifie que la methode est amorcable
=========================================================*/
if( !is_callable($this->getFunctionCaller()) ){
$this->error = ManagerError::UncallableMethod;
return new ModuleResponse($this->error);
}
/* [3] On amorce la methode
=========================================================*/
$returned = call_user_func( $this->getFunctionCaller(), $this->params );
/* [4] Vérification des erreurs et paramètres
=========================================================*/
/* (1) Vérification de l'erreur retournée, si pas Success, on retourne l'erreur */
if( isset($returned['ModuleError']) && $returned['ModuleError'] != ManagerError::Success ){
$this->error = $returned['ModuleError'];
return new ModuleResponse($this->error);
}
/* (2) Vérification du contenu, si pas défini */
if( !isset($returned['body']) ){
$this->error = ManagerError::ParamError;
return new ModuleResponse($this->error);
}
/* (3) Si @headers n'est pas défini on met par défaut */
if( !isset($returned['headers']) || !is_array($returned['headers']) )
$returned['headers'] = [];
$fromAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
/* [5] Si la requête vient d'ajax on crée un fichier temporaire et on renvoie son URL
=========================================================*/
if( $fromAjax ){
$tmpfname = '/tmp/download_'.uniqid().'.php';
$bodyfname = __BUILD__.'/tmp/content_'.uniqid().'.php';
/* (1) On crée le fichier temporaire */
$tmpfnameroot = __BUILD__.$tmpfname;
$tmpfile = fopen($tmpfnameroot, 'w');
fwrite($tmpfile, '<?php'.PHP_EOL);
/* (2) Script qui écrira les headers */
foreach($returned['headers'] as $header=>$value)
fwrite($tmpfile, "header(\"$header: $value\");".PHP_EOL);
/* (3) Script qui écrira le contenu */
// 1) On écrit le contenu dans un fichier temporaire (et oui encore)
$bodyfile = fopen($bodyfname, 'w');
fwrite($bodyfile, $returned['body']);
fclose($bodyfile);
chmod($bodyfname, 0775);
fwrite($tmpfile, "readfile('$bodyfname');".PHP_EOL);
/* (4) Script qui supprimera les fichiers temporaires */
fwrite($tmpfile, "unlink('$bodyfname');".PHP_EOL);
fwrite($tmpfile, "unlink(__FILE__);".PHP_EOL);
fwrite($tmpfile, '?>'.PHP_EOL);
/* (5) On ferme le fichier */
fclose($tmpfile);
chmod($tmpfnameroot, 0775);
$response = new ModuleResponse(ManagerError::Success);
$response->append('link', $tmpfname);
return $response;
/* [6] Gestion du download direct si pas AJAX
=========================================================*/
}else{
/* (1) On définit les headers */
foreach($returned['headers'] as $header=>$value)
header($header.': '.$value);
/* (2) On affiche le contenu */
echo $returned['body'];
return true;
}
}
/* DESERIALISATION A PARTIR DES DONNEES POST
*
* @url<String> Contenu de l'url après api/ (si existe)
* @post<Array> Tableau des donnes $_POST => @path + @data (opt)
*
* @return instance<ModuleRequest> Retourne un objet de type <ModuleRequest>
*
*/
public static function fromPost($url, $post){
/* [0] Verification de l'authentification
=========================================================*/
// On definit le token
$token = isset($_SERVER['PHP_AUTH_DIGEST']) ? $_SERVER['PHP_AUTH_DIGEST'] : null;
/* [1] On verifie que le @path est renseigne
=========================================================*/
/* (1) Si le path est dans @url */
$pathInUrl = is_string($url[0]) && strlen($url[0]) > 0 && preg_match('#^([\w_-]+)/([\w_-]+)/?$#', $url[0], $urlMatches);
// On l'utilise pour le chemin
if( $pathInUrl )
$post['path'] = $urlMatches[1].'/'.$urlMatches[2];
/* (2) On vérifie dans tous les cas si le path existe */
if( !isset($post['path']) )
return new ModuleRequest();
/* [2] On verifie que @data est renseigne
=========================================================*/
// Si variable n'existe pas, on cree un tableau vide
$params = $post;
// On retire le @path de @params
unset($params['path']);
/* [3] On met les paramètres JSON en JSON (si ils décodent sans erreur)
=========================================================*/
foreach($params as $name=>$value){
$json = json_decode( $value, true );
// Si aucune erreur, on affecte la valeur
if( !is_null($json) )
$params[$name] = $json;
}
/* [4] On retourne une instance de <ModuleRequest>
=========================================================*/
// On cree notre requete avec le token
return new ModuleRequest($post['path'], $params, $token);
}
/* VERIFICATION DU FORMAT ET DE LA COHERENCE DU CHEMIN SPECIFIE
*
* @path<String> String correspondant au chemin de delegation ("module/methode")
*
* @return validity<Boolean> Retourne si oui ou non l'objet est correct
*
*/
private function checkPath($path){
/* [1] Verification format general
=========================================================*/
if( !preg_match('#^([\w_-]+)/([\w_-]+)$#i', $path, $matches) ){ // Si mauvais format
$this->error = ManagerError::WrongPathModule;
return false;
}
// On recupere les donnes de la regex
$module = $matches[1];
$method = $matches[2];
/* [2] Verification de l'existence du module (conf)
=========================================================*/
if( !array_key_exists($module, $this->modules) ){ // Si le module n'est pas specifie dans la conf
$this->error = ManagerError::UnknownModule;
return false; // On retourne FALSE, si erreur
}
/* [3] Verification de l'existence de la methode (conf)
=========================================================*/
if( array_key_exists($method, $this->modules[$module]) === false ){ // Si la methode n'est pas specifie dans la conf
$this->error = ManagerError::UnknownMethod;
return false; // On retourne FALSE, si erreur
}
/* [4] Enregistrement du chemin et renvoi de SUCCESS
=========================================================*/
$this->path = [
'module' => $module,
'method' => $method
];
return true;
}
/* RETOURNE SI ON A LA PERMISSION D'EXECUTER CETTE METHODE
*
* @token<String> Token d'acces a l'API (OPTIONNEL)
*
* @return permission<bool> Retourne si on a les droits ou pas pour executer cette methode
*
*/
private function checkPermission($token=null){
/* [1] On recupere les informations utiles
=========================================================*/
// On recupere le nom de la methode
$method = $this->modules[$this->path['module']][$this->path['method']];
// Si aucune permission n'est definie
if( !isset($method['permissions']) ) return true;
/* [2] Gestion si un @token est defini
=========================================================*/
if( Checker::run('hash', $token) ){
/* (1) On verifie que le token est valide */
$checkToken = new Repo('token/check', [$token] );
$token_permissions = $checkToken->answer();
// Si le token est invalide, on retourne une erreur -> FAUX
if( $token_permissions === false ){
$this->error = ManagerError::TokenError;
return false;
}
$local_permissions = $token_permissions;
/* [3] Gestion si aucun token, avec utilisateur connecté
=========================================================*/
}else if( isset($_SESSION['permission']) )
$local_permissions = $_SESSION['permission'];
// Si ni token, ni SESSION, erreur
else{
$this->error = ManagerError::PermissionError;
return false;
}
/* [4] Verification des droits parmi les permissions donnees
=========================================================*/
/* (1) On recupere la liste des permissions possibles */
$permissions = $method['permissions'];
/* (2) Si aucune permission n'est definie, on laisse l'acces */
if( !$permissions == 0 ) return true;
/* (3) On verifie qu'il y a aucune permission manquante */
foreach($permissions as $permission)
if( !in_array($permission, $local_permissions) ){
$this->error = ManagerError::PermissionError;
return false;
}
/* [5] On retourne FAUX si aucun droit n'a ete trouve
=========================================================*/
return true;
}
/* VERIFICATION DU TYPE DES PARAMETRES ENVOYES
*
* @params<Array> Tableau associatif contenant les parametres
* @params peut se voir rajouter les paramètres optionnels s'ils ne sont pas renseignés (initialisés à NULL)
*
* @return correct<bool> Retourne si oui ou non les parametres ont le bon type
*
*/
private function checkParams(&$params){
/* [1] On verifie qu'il ne manque aucun parametre
=========================================================*/
// Si @params n'est pas un tableau
if( !is_array($params) ) return false;
$method = $this->modules[$this->path['module']][$this->path['method']];
/* [2] Si le type est defini, pour chaque param, on teste
=========================================================*/
foreach($method['parameters'] as $name=>$paramsdata){
/* (1) On récupère si le paramètre est optionnel ou pas */
$optional = isset($paramsdata['optional']) && $paramsdata['optional'] === true;
/* (2) Récupère si le paramètre est un fichier et définit comme de type 'FILE' */
$isFile = isset($paramsdata['type']) && $paramsdata['type'] == 'FILE' && isset($_FILES[$name]);
/* (3) Si le paramètre est obligatoire et qu'il n'est pas donné -> erreur */
if( !isset($params[$name]) && !$optional && !$isFile )
return false;
/* (4) Si le type n'est pas defini, on a pas besoin de le vérifier */
if( !isset($paramsdata['type']) )
continue;
/* (5) Si le paramètre est optionnel et n'est pas donné */
if( $isFile || $optional && (!isset($params[$name]) || is_null($params[$name])) ){
// On le crée le param optionnel avec la valeur NULL
$params[$name] = null;
// On donne une référence vers le fichier, si c'en est un
if( $isFile )
$params[$name] = &$_FILES[$name];
continue; // On passe au paramètre suivant
/* (6) Si le paramètre est renseigné */
}else
// Si la verification est fausse, on retourne faux
if( !Checker::run($paramsdata['type'], $params[$name]) )
return false;
}
/* [3] Gestion du retour, si tout s'est bien passe
=========================================================*/
return true;
}
/* AJOUT DES OPTIONS A PARTIR DE LA CONFIGURATION
*
*/
private function buildOptions(){
/* [0] On récupère les options de la méthode en cours
=========================================================*/
$method = $this->modules[$this->path['module']][$this->path['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']) )
return true;
/* (2) Par défaut on définit les options par défaut */
$this->options = self::$default_options;
/* (3) On récupère les options données */
$options = $method['options'];
/* [1] Gestion des différentes options
=========================================================*/
foreach($options as $option=>$value){
/* (1) On ne prend en compte l'option que si elle est dans les options par défaut */
if( !isset(self::$default_options[$option]) )
continue;
/* (2) Le type de la valeur doit être le même que celui de la valeur par défaut */
if( gettype($value) != gettype(self::$default_options[$option]) )
continue;
/* (3) Si tout est bon, on définit la valeur */
$this->options[$option] = $value;
}
return true;
}
/* RENVOI LE CHEMIN D'AMORCAGE DE LA METHODE
*
* @return path<Array> Retourne le chemin d'amorcage de la requete
*
*/
private function getFunctionCaller(){
return [ '\\api\\module\\'.$this->path['module'], $this->path['method'] ];
}
}
?>

View File

@ -0,0 +1,163 @@
<?php
namespace api\core;
use \manager\ManagerError;
// FORMAT:
//
// path: "nomModule/nomMethode"
// data1: {donnee1}
// data2: {donnee2}
// ...
//
//
//
//
class ModuleResponse{
// Attributs prives utiles (initialisation)
private $data;
public $error;
/* CONSTRUCTEUR D'UNE REPONSE DE MODULE
*
* @error<ModuleError> Erreur passee par la requete (si existe)
*
*/
public function __construct($error=ManagerError::Success){
$this->data = [];
$this->error = $error;
}
/* AJOUTE UNE DONNEE A LA REPONSE
*
* @key<String> Le nom de la valeur a ajouter
* @value<mixed*> La valeur a ajouter
*
*/
public function append($key, $value){
// Ajoute une entree pour la cle @key et de valeur @value
$this->data[$key] = $value;
return $this;
}
/* AJOUTE TOUTES LES DONNEES A LA REPONSE
*
* @dataset<Array> Le tableau associatif correspondant a la reponse
*
*/
public function appendAll($dataset){
// Si ce n'est pas un tableau, on ne fais rien
if( !is_array($dataset) ) return $this;
// Si une valeur contient une erreur
if( array_key_exists('ModuleError', $dataset) ){
// On definit cette erreur
$this->error = $dataset['ModuleError'];
// On enleve cette entree des donnees
unset($dataset['ModuleError']);
}
// Ajoute une entree pour la cle @key et de valeur @value
$this->data = $dataset;
return $this;
}
/* RECUPERE UNE DONNEE DE LA REPONSE
*
* @key<String> Le nom de la valeur a recuperer
*
* @return value<mixed*> La valeur a cette cle
* @return error<null> Retourne NULL si aucune valeur pour cette cle
*
*/
public function get($key){
// Si la valeur de cle @key n'existe pas, on retourne NULL
if( !isset($this->data[$key]) )
return null;
// Sinon, on retourne la valeur associee
return $this->data[$key];
}
/* RECUPERE TOUTES LES DONNEES DE LA REPONSE
*
* @return data<Array> Les donnees de la reponse
*
*/
public function getAll(){
// Sinon, on retourne la valeur associee
return $this->data;
}
/* SERIALISATION A PARTIR DES DONNEES
*
* @return json<String> Retourne les donnees serialisees
*
*/
public function serialize(){
// Code Http
ManagerError::setHttpCode($this->error);
// Type de contenu
header('Content-Type: application/json; charset=utf-8');
// On rajoute l'erreur au message
$returnData = array_merge(
[
'ModuleError' => $this->error,
'ErrorDescription' => ManagerError::explicit($this->error)
],
$this->data
);
return json_encode($returnData);
}
}
?>

2
build/manager/.htaccess Normal file
View File

@ -0,0 +1,2 @@
Order deny,allow
Deny from all

View File

@ -0,0 +1,127 @@
<?php
namespace manager;
class ManagerError{
/* SUCCESS */
const Success = 0;
/* Parsage json */
const ParsingFailed = 1;
/* ResourceDispatcher */
// Drapeaux invalides
const InvalidFlags = 2;
// Fichier inexistant
const UnreachableResource = 3;
/* ModuleRequest */
// Le @path n'est pas renseigne
const MissingPath = 4;
// Verification de la coherence du chemin (existe dans la conf)
const WrongPathModule = 5;
// Module non specifie dans la conf
const UnknownModule = 6;
// Methode non specifie pour ce Module dans la conf
const UnknownMethod = 7;
// Methode inamorcable
const UncallableMethod = 8;
// Erreur de parametre(s)
const ParamError = 9;
// Erreur dans le traitement
const ModuleError = 10;
/* Repo */
// Verification de la coherence du chemin (existe dans la conf)
const WrongPathRepo = 11;
// Module non specifie dans la conf
const UnknownRepo = 12;
// Erreur dans le traitement
const RepoError = 13;
/* Database */
// Erreur lors de la creation d'un objet PDO (connection)
const PDOConnection = 14;
/* API token */
// Token inexistant ou faux
const TokenError = 15;
const PermissionError = 16;
/* Erreur d'UPLOAD */
const UploadError = 17;
// Mauvais format de fichier
const FormatError = 18;
/* Erreur au niveau javascript */
//const JavascriptError = 19; // -> géré en js
/* EXPLICITE UN CODE D'ERREUR
*
* @error<Integer> Code d'erreur
*
* @return explicit<String> Description explicite du code d'erreur
*
*/
public static function explicit($error){
switch($error){
case self::Success: return "Tout s'est bien deroulé."; break;
case self::ParsingFailed: return "La lecture du fichier JSON ou XML a echouée."; break;
case self::InvalidFlags: return "Les spécifications (drapeaux) sont incorrects."; break;
case self::UnreachableResource: return "La ressource n'existe pas (404)."; break;
case self::MissingPath: return "Le chemin de délégation n'a pas été renseigné."; break;
case self::WrongPathModule: return "Le chemin de délégation est incorrect ('nomModule/nomMethode')."; break;
case self::WrongPathRepo: return "Le chemin de délégation est incorrect ('nomRepo/nomMethode')."; break;
case self::UnknownModule: return "Le module n'existe pas."; break;
case self::UnknownRepo: return "Le repo n'existe pas."; break;
case self::UnknownMethod: return "Le methode n'existe pas."; break;
case self::UncallableMethod: return "Le methode n'est pas amorçable."; break;
case self::ParamError: return "Un ou plusieurs paramètres sont manquants ou incorrects."; break;
case self::ModuleError: return "Erreur lors du traitement du module."; break;
case self::RepoError: return "Erreur lors du traitement du repo."; break;
case self::PDOConnection: return "La connexion avec la base de données a echouée."; break;
case self::TokenError: return "Le token de connection est absent, érroné ou expiré."; break;
case self::PermissionError: return "Vous n'avez pas la permission d'effectuer cette action."; break;
case self::UploadError: return "Une erreur d'upload est survenue."; break;
case self::FormatError: return "Le fichier n'est pas au bon format."; break;
default: return "Description d'erreur inconnue..."; break;
}
// Erreur inconnue
return null;
}
public static function setHttpCode($error){
http_response_code( $error == self::Success ? 200 : 417 );
}
}
?>

View File

@ -0,0 +1,63 @@
<?php
/**************************************/
/* Classe de gestion de route (match) */
/**************************************/
namespace router\core;
class Route{
// ATTRIBUTS
private $pattern;
private $callback;
private $matches = [];
/* Initialise la route
*
* @pattern<String> Pattern correspondant a la route
* @callback<Function> Fonction de callback de la route
*
* @return this<Route> Retour de l'instance courante
*
*/
public function __construct($pattern, $callback){
// On enregistre la fonction de callback
$this->callback = $callback;
// On formatte le pattern en regexp
$this->pattern = '#^'.$pattern.'$#';
return $this;
}
/* Verifie si l'URL correspond a la route
*
* @url<String> URL pour laquelle on veut verifier
*
* @return match<Boolean> TRUE si match sinon FAUX
*
*/
public function match($url){
// Si ne match pas -> FALSE
if( !preg_match($this->pattern, $url, $matches) )
return false;
// On supprime le premier match global
array_shift($matches);
$this->matches = $matches;
return true;
}
/* Amorcage de la fonction de callback
*
*/
public function call(){
return call_user_func($this->callback, $this->matches);
}
}
?>

View File

@ -0,0 +1,91 @@
<?php
/*************************************************/
/* Classe de gestion des routes (URL/ressources) */
/*************************************************/
namespace router\core;
class Router{
// ATTRIBUTS
private $url;
private $routes;
/* Initialise le routeur
*
* @url<String> l'URL de la page courante
*
* @return this<Router> Retour de l'instance courante
*
*/
public function __construct($url){
$this->url = $url;
// On initialise les routes
$this->routes = [
'GET' => [],
'POST' => []
];
return $this;
}
/* Ajoute une route GET
*
* @pattern<String> le format de l'URL associe
* @callback<Function> function a appeler si l'URL correspond
*
* @return this<Router> Retour de l'instance courante
*
*/
public function get($pattern, $callback){
array_push(
$this->routes['GET'],
new Route($pattern, $callback)
);
return $this;
}
/* Ajoute une route POST
*
* @pattern<String> le format de l'URL associe
* @callback<Function> function a appeler si l'URL correspond
*
* @return this<Router> Retour de l'instance courante
*
*/
public function post($pattern, $callback){
array_push(
$this->routes['POST'],
new Route($pattern, $callback)
);
return $this;
}
/* Demarre le routeur
*
* @return this Retour de l'instance courante
*
*/
public function run(){
$httpMethod = $_SERVER['REQUEST_METHOD'];
// Si aucune route pour la methode courante -> false
if( count($this->routes[$httpMethod]) <= 0 )
return false;
// Pour chaque route
foreach($this->routes[$httpMethod] as $route){
// Si la route match
if( $route->match($this->url) )
return $route->call(); // On l'amorce
}
// Retourne false si erreur
return false;
}
}
?>

2
config/.htaccess Normal file
View File

@ -0,0 +1,2 @@
Order deny,allow
Deny from all

3
config/modules.json Executable file
View File

@ -0,0 +1,3 @@
{
}

13
config/server.json Normal file
View File

@ -0,0 +1,13 @@
{
"local" : {
"host" : "http://prod-releaser/",
"root" : "/"
},
"remote" : {
"host" : "https://prod-releaser.xdrm.io/",
"root" : "/"
}
}

4
public_html/.htaccess Normal file
View File

@ -0,0 +1,4 @@
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

49
public_html/index.php Normal file
View File

@ -0,0 +1,49 @@
<?php define('__ROOT__', dirname(dirname(__FILE__)) );
require_once __ROOT__.'/autoloader.php';
use \router\core\Router;
use \api\core\ModuleRequest;
use \api\core\ModuleResponse;
use \manager\ManagerError;
// var_dump($_SESSION);
/*******************************************/
/* DEBUGGER */
/*******************************************/
debug();
/*******************************************/
/* [3] On initialise le routeur
===================================================*/
/* (1) New Router */
$R = new Router( $_GET['url'] );
/* [2] host.xxx/api/{module}/{method} -> api
=========================================================*/
$R->post('api(?:/(.*))?', function($url){
$request = ModuleRequest::fromPost($url, $_POST);
$answer = $request->dispatch();
// Si c'est une réponse
if( $answer instanceof ModuleResponse )
echo $answer->serialize();
});
/* [3] Any other URL -> homepage
=========================================================*/
$R->get('.+', function(){ header(__REDIRECT__); });
$R->post('.+', function(){ header(__REDIRECT__); });
/* [8] Launch Router
===================================================*/
$R->run();
?>