diff --git a/console.php b/console.php index 2f55be8..e18cbbd 100755 --- a/console.php +++ b/console.php @@ -7,20 +7,21 @@ ############## # INCLUSIONS # ############## - //On va inclure l'ensemble des fichiers necessaires - require_once('./mvc/constants.php'); - require_once('./mvc/autoload.php'); - require_once('./mvc/conn_bdd.php'); - require_once('./mvc/secho.php'); - require_once('./mvc/Controller.php'); - require_once('./mvc/Router.php'); - require_once('./mvc/Model.php'); + require_once(__DIR__ . '/mvc/constants.php'); + require_once(PWD . 'mvc/autoload.php'); + require_once(PWD . 'mvc/conn_bdd.php'); + require_once(PWD . 'mvc/secho.php'); + require_once(PWD . 'mvc/Controller.php'); + require_once(PWD . 'mvc/ApiController.php'); + require_once(PWD . 'mvc/Router.php'); + require_once(PWD . 'mvc/Model.php'); + require_once(PWD . 'mvc/Console.php'); ######### # MODEL # ######### //On va appeler un modèle, est l'initialiser - $db = new DataBase($bdd);; + $db = new DataBase($bdd); //On va ajouter les réglages globaux de RaspiSMS modifiables via l'interface $settings = $db->getFromTableWhere('settings'); @@ -33,23 +34,5 @@ # ROUTAGE # ########### //Partie gérant l'appel des controlleurs - $controller = new internalConsole(); - - $options = getopt('c:'); - - if (!isset($options['c'])) //Si on a pas reçu de methode à appeler - { - echo "Vous devez précisez un script à appeler (-c 'nom du script').\n"; - echo "Pour plus d'infos, utilisez -c 'help'\n"; - exit(1); //Sorti avec erreur - } - - if (!method_exists($controller, $options['c'])) //Si la méthode reçue est incorrect - { - echo "Vous avez appelé un script incorrect.\n"; - echo "Pour plus d'infos, utilisez -c 'help'\n"; - exit(2); //Sorti avec erreur - } - - $controller->$options['c'](); //On appel la fonction - + $console = new Console($argv); + $console->executeCommand($console->getCommand()); diff --git a/controllers/internalConsole.php b/controllers/internalConsole.php index 6c4b5ad..5788b44 100755 --- a/controllers/internalConsole.php +++ b/controllers/internalConsole.php @@ -1,73 +1,6 @@ array( - 'description' => 'Cette commande permet d\'envoyer les SMS programmés qui doivent l\'êtres.', - 'requireds' => array(), - 'optionals' => array(), - ), - 'parseReceivedSMS' => array( - 'description' => 'Cette commande permet d\'enregistrer un SMS, et de l\'analyser pour voir s\'il contient une commande. Pour cela, il analyse le dossier PWD_RECEIVEDS', - 'requireds' => array( - ), - 'optionals' => array(), - ), - 'sendTransfers' => array( - 'description' => 'Cette commande permet d\'envoyer par mails les sms à transférés.', - 'requireds' => [], - 'optionals' => [], - ), - ); - - $message = "Vous êtes ici dans l'aide de la console.\n"; - $message .= "Voici la liste des commandes disponibles : \n"; - - //On écrit les texte pour la liste des commandes dispos - foreach ($commands as $name => $value) - { - $requireds = isset($value['requireds']) ? $value['requireds'] : array(); - $optionals = isset($value['optionals']) ? $value['optionals'] : array(); - - $message .= ' ' . $name . ' : ' . $value['description'] . "\n"; - $message .= " Arguments obligatoires : \n"; - if (!count($requireds)) - { - $message .= " Pas d'argument\n"; - } - else - { - foreach ($requireds as $argument => $desc) - { - $message .= ' - ' . $argument . ' : ' . $desc . "\n"; - } - } - - $message .= " Arguments optionnels : \n"; - - if (!count($optionals)) - { - $message .= " Pas d'argument\n"; - } - else - { - foreach ($optionals as $argument => $desc) - { - $message .= ' - ' . $argument . ' : ' . $desc . "\n"; - } - } - } - - echo $message; - } - /** * Cette fonction envoie tous les SMS programmés qui doivent l'être */ @@ -472,6 +405,8 @@ echo "Query do to " . $webhookQuerie['url'] . " with datas " . $datas . "\n"; } + $db->deleteWebhookQueriesIn($webhookQueriesIds); + //On attend 2 secondes sleep(2); } diff --git a/controllers/internalTools.php b/controllers/internalTools.php index 4d33043..c916377 100755 --- a/controllers/internalTools.php +++ b/controllers/internalTools.php @@ -51,6 +51,9 @@ case 'COMMAND_ADD' : $logo = 'fa-terminal'; break; + case 'WEBHOOK_ADD' : + $logo = 'fa-plug'; + break; default : $logo = 'fa-question'; } diff --git a/controllers/webhooks.php b/controllers/webhooks.php index b6b1e66..de3e497 100755 --- a/controllers/webhooks.php +++ b/controllers/webhooks.php @@ -108,7 +108,7 @@ return false; } - $db->insertIntoTable('events', ['type' => 'WEBHOOKS_ADD', 'text' => 'Ajout webhook : ' . $type . ' => ' . $url]); + $db->insertIntoTable('events', ['type' => 'WEBHOOK_ADD', 'text' => 'Ajout webhook : ' . array_search($type, internalConstants::WEBHOOK_TYPE) . ' (' . $url . ')']); $_SESSION['successmessage'] = 'Le webhook a bien été créé.'; header('Location: ' . $this->generateUrl('webhooks')); diff --git a/index.php b/index.php index eb8ffb5..cdd9daf 100755 --- a/index.php +++ b/index.php @@ -9,6 +9,7 @@ require_once('./mvc/conn_bdd.php'); require_once('./mvc/secho.php'); require_once('./mvc/Controller.php'); + require_once('./mvc/ApiController.php'); require_once('./mvc/Router.php'); require_once('./mvc/Model.php'); diff --git a/model/DataBase.php b/model/DataBase.php index 75f7520..a36cfc4 100755 --- a/model/DataBase.php +++ b/model/DataBase.php @@ -602,6 +602,26 @@ return $this->runQuery($query, $params); } + /** + * Supprime tous les webhooks dont l'id fait partie du tableau fourni + * @param $webhooks_ids : Tableau des id des webhooks à supprimer + * @return int : Nombre de lignes supprimées + */ + public function deleteWebhooksIn($webhooks_ids) + { + $query = " + DELETE FROM webhooks + WHERE id "; + + //On génère la clause IN et les paramètres adaptés depuis le tableau des id + $generted_in = $this->generateInFromArray($webhooks_ids); + $query .= $generted_in['QUERY']; + $params = $generted_in['PARAMS']; + + return $this->runQuery($query, $params, self::ROWCOUNT); + } + + /***************************************/ /* PARTIE DES REQUETES WEBHOOK_QUERIES */ /***************************************/ @@ -628,18 +648,18 @@ } /** - * Supprime tous les webhooks dont l'id fait partie du tableau fourni - * @param $webhooks_ids : Tableau des id des webhooks à supprimer + * Supprime tous les webhook_queries dont l'id fait partie du tableau fourni + * @param $webhook_queries_ids : Tableau des id des webhook_queries à supprimer * @return int : Nombre de lignes supprimées */ - public function deleteWebhooksIn($webhooks_ids) + public function deleteWebhookQueriesIn($webhook_queries_ids) { $query = " - DELETE FROM webhooks + DELETE FROM webhook_queries WHERE id "; //On génère la clause IN et les paramètres adaptés depuis le tableau des id - $generted_in = $this->generateInFromArray($webhooks_ids); + $generted_in = $this->generateInFromArray($webhook_queries_ids); $query .= $generted_in['QUERY']; $params = $generted_in['PARAMS']; diff --git a/mvc/ApiController.php b/mvc/ApiController.php new file mode 100755 index 0000000..7732a44 --- /dev/null +++ b/mvc/ApiController.php @@ -0,0 +1,128 @@ +method = 'DELETE'; + break; + case 'patch' : + $this->method = 'PATCH'; + break; + case 'post' : + $this->method = 'POST'; + break; + case 'put' : + $this->method = 'PUT'; + break; + default : + $this->method = 'GET'; + } + + //On construit aussi le controller traditionnel + parent::__construct(); + } + + /** + * Cette fonction permet d'effectuer n'importe quelle opération sur le header en retournant le controller en cours + * @param string $key : La clef du header + * @param string $value : La valeur à donner + * @return ApiController : On retourne l'API controlleur lui meme pour pouvoir chainer + */ + public function setHeader ($key, $value) + { + header($key . ': ' . $value); + return $this; + } + + /** + * Cette fonction permet de définir un code de retour HTTP + * @param int $code : Le numéro du code de retour HTTP + * @return ApiController : On retourne l'API controlleur lui meme pour pouvoir chainer + */ + public function setHttpCode ($code) + { + http_response_code($code); + return $this; + } + + /** + * Cette fonction permet de définir un code de retour automatiquement selon le contexte du controller (c'est à dire si on l'appel en POST, en GET, etc.) + * @param boolean $success : Si la requete est un succes ou non (par défaut à true) + * @return ApiController : On retourne l'API controlleur lui meme pour pouvoir chainer + */ + public function autoHttpCode ($success = true) + { + $responseCodes = array( + 'GET' => array( + 'success' => 200, + 'fail' => 404, + ), + 'DELETE' => array( + 'success' => 204, + 'fail' => 400, + ), + 'PATCH' => array( + 'success' => 204, + 'fail' => 400, + ), + 'POST' => array( + 'success' => 201, + 'fail' => 400, + ), + 'PUT' => array( + 'success' => 204, + 'fail' => 400, + ), + ); + + $key = $success ? 'success' : 'fail'; + + return $this->setHttpCode($responseCodes[$this->method][$key]); + } + + /** + * Cette fonction permet de faire un retour sous forme de json + * @param array $datas : Les données à retourner sous forme de json + * @param boolean $secure : Défini si l'affichage doit être sécurisé contre les XSS, par défaut true + * @return ApiController : On retourne l'API controlleur lui meme pour pouvoir chainer + */ + public function json ($datas, $secure = true) + { + header('Content-Type: application/json'); + + if ($secure) + { + echo htmlspecialchars(json_encode($datas), ENT_NOQUOTES); + } + else + { + echo json_encode($datas); + } + + return $this; + } + + /** + * Cette fonction permet de fixer la location renvoyée en HTTP + * @param string $location : La location à renvoyer + * @return ApiController : On retourne l'API controlleur lui meme pour pouvoir chainer + */ + public function setLocation ($location) + { + header('Location: ' . $location); + return $this; + } + } diff --git a/mvc/Console.php b/mvc/Console.php new file mode 100755 index 0000000..a66e843 --- /dev/null +++ b/mvc/Console.php @@ -0,0 +1,307 @@ +command = $command; + } + else + { + $this->command = []; + } + } + + //Getters et setters + public function getCommand() + { + return $this->command; + } + + public function setCommand($value) + { + $this->command = $value; + } + + /** + * Cette méthode vérifie si une commande demande explicitement d'appeler l'aide + * @param array $command : La commande appelée + * @param boolean : Vrai si on doit appeler l'aide, faux sinon + */ + public function parseForHelp ($command) + { + return (isset($command[1]) && $command[1] == '--help'); + } + + /** + * Retourne le controlleur à appeler d'après une commande + * @param array $command : La commande à analyser + * @return mixed : Le nom du controlleur à appeler si la commande en contient un, et faux sinon ou si le controlleur n'existe pas + */ + public function parseForController($command) + { + //Si on doit chercher de l'aide globale, on retire la demande d'aide + if ($this->parseForHelp($command)) + { + unset($command[1]); + $command = array_values($command); + } + + //Pas de controlleur à appeler + if (!isset($command[1])) + { + return false; + } + + $controllerName = $command[1]; + + if (!file_exists(PWD_CONTROLLER . $controllerName . '.php')) + { + return false; + } + + return $controllerName; + } + + /** + * Retourne la méthode à appeler d'après une commande + * @param array $command : La commande à analyser + * @return mixed : Le nom de la méthode à appeler si la commande en contient une, et faux sinon ou si la méthode n'existe pas pour le controlleur demandé + */ + public function parseForMethod($command) + { + //Si on doit chercher de l'aide globale, on retire la demande d'aide + if ($this->parseForHelp($command)) + { + unset($command[1]); + $command = array_values($command); + } + + //Le controlleur n'existe pas + if (!$controllerName = $this->parseForController($command)) + { + return false; + } + + //Si on a pas fourni de méthode + if (!isset($command[2])) + { + return false; + } + + $methodName = $command[2]; + + //La méthode n'existe pas + if (!method_exists($controllerName, $methodName)) + { + return false; + } + + return $methodName; + } + + /** + * Retourne les paramètres d'une méthode d'après une commande + * @param array $command : La commande à analyser + * @return mixed : Le tableau des paramètres fournis (au format 'name' => 'value') ou faux si la méthode ou le controlleur n'existe pas + */ + public function parseForParams($command) + { + //Si on doit chercher de l'aide globale, on retire la demande d'aide + if ($this->parseForHelp($command)) + { + unset($command[1]); + $command = array_values($command); + } + + //Le controlleur n'existe pas + if (!$controllerName = $this->parseForController($command)) + { + return false; + } + + //La méthode n'existe pas + if (!$methodName = $this->parseForMethod($command)) + { + return false; + } + + //On construit la liste des arguments passés à la commande au format 'name' => 'value' + unset($command[0], $command[1], $command[2]); + $command = array_values($command); + $params = []; + + foreach ($command as $param) + { + $param = explode('=', $param, 2); + $paramName = str_replace('--', '', $param[0]); + $paramValue = $param[1]; + $params[$paramName] = $paramValue; + } + + return $params; + } + + /** + * Vérifie si une commande contient tous les paramètres obligatoires d'une méthode et retourne un tableau des arguments remplis + * @param array $command : La commande à analyser + * @return mixed : Si tout est bon, un tableau un contenant les différents paramètres dans l'ordre où ils doivent êtres passé à la méthode. Sinon, si par exemple un paramètre obligatoire est manquant false. + */ + public function checkParametersValidityForCommand($command) + { + //Le controlleur n'existe pas + if (!$controllerName = $this->parseForController($command)) + { + return false; + } + + //La méthode n'existe pas + if (!$methodName = $this->parseForMethod($command)) + { + return false; + } + + //Les paramètres retournes une erreur + $commandParams = $this->parseForParams($command); + if ($commandParams === false) + { + return false; + } + + //On construit la liste des arguments de la méthode, dans l'ordre + $reflection = new ReflectionMethod($controllerName, $methodName); + $methodArguments = []; + + foreach ($reflection->getParameters() as $parameter) + { + //Si le paramètre n'est pas fourni et n'as pas de valeur par défaut + if (!array_key_exists($parameter->getName(), $commandParams) && !$parameter->isDefaultValueAvailable()) + { + return false; + } + + //Si on a une valeur par défaut dispo, on initialise la variable avec + if ($parameter->isDefaultValueAvailable()) + { + $methodArguments[$parameter->getName()] = $parameter->getDefaultValue(); + } + + //Si la variable n'existe pas, on passe + if (!array_key_exists($parameter->getName(), $commandParams)) + { + continue; + } + + //On ajoute la variable dans le tableau des arguments de la méthode + $methodArguments[$parameter->getName()] = $commandParams[$parameter->getName()]; + } + + return $methodArguments; + } + + /** + * Cette méthode retourne le texte d'aide d'un controller ou d'une de ses méthodes + * @param array $command : La commande appelée + * @param string $controller : Le nom du controller pour lequel on veux l'aide, ou false (par défaut) + * @param string $method : La nom de la méthode pour laquelle on veux de l'aide, ou false (par défaut) + * @param boolean $missingArguments : Si il manque des arguments obligatoires pour la méthode (par défaut faux) + * @param string : Le texte d'aide à afficher + */ + public function getHelp ($command, $controller = false, $method = false, $missingArguments = false) + { + $retour = ''; + + $retour .= "Aide : \n"; + + //Si pas de controlleur, on sort l'aide par défaut + if (!$controller) + { + $retour .= "Vous n'avez pas fournit de controller à appeler. Pour voir l'aide : " . $command[0] . " --help \n"; + return $retour; + } + + if ($missingArguments) + { + $retour .= "Vous n'avez pas fournis tous les arguments obligatoire pour cette fonction. Pour rappel : \n"; + } + + //Si on a pas définie la méthode, on les fait toutes, sinon juste celle définie + if (!$method) + { + $retour .= 'Aide du controller ' . $controller . "\nMéthodes : \n"; + $reflection = new ReflectionClass($controller); + $reflectionMethods = $reflection->getMethods(); + } + else + { + $reflectionMethods = [new ReflectionMethod($controller, $method)]; + $retour .= 'Aide du controller ' . $controller . ' et de la méthode ' . $method . "\n"; + } + + //Pour chaque méthode, on affiche l'aide + foreach ($reflectionMethods as $reflectionMethod) + { + $retour .= " " . $reflectionMethod->getName(); + + //On ajoute chaque paramètre au retour + foreach ($reflectionMethod->getParameters() as $parameter) + { + $retour .= ' --' . $parameter->getName() . "=isDefaultValueAvailable() ? ' (par défaut, ' . gettype($parameter->getDefaultValue()) . ':' . str_replace(PHP_EOL, '', print_r($parameter->getDefaultValue(), true)) . ')': '') . ">"; + } + + $retour .= "\n"; + } + + return $retour; + } + + /** + * Cette méthode tente d'appeler le controlleur et la méthode correspondant à la commande, avec les arguments demandés + * @param array $command : La commande appelée + */ + public function executeCommand ($command) + { + //Si on a pas de controller à appeler + if (!$controller = $this->parseForController($command)) + { + echo $this->getHelp($command); + return false; + } + + //Si on a pas de méthode à appeler + if (!$method = $this->parseForMethod($command)) + { + echo $this->getHelp($command, $controller); + return false; + } + + //Si on a pas tous les arguments necessaires à la méthode + $params = $this->checkParametersValidityForCommand($command); + if ($params === false) + { + echo $this->getHelp($command, $controller, $method, true); + return false; + } + + //Si on doit appeler l'aide + if ($this->parseForHelp($command)) + { + echo $this->getHelp($command, $controller, $method); + return false; + } + + //Si tout est bien ok, on appel la méthode + return call_user_func_array([$controller, $method], $params); + } + + } diff --git a/mvc/Model.php b/mvc/Model.php index 15404be..2f0c238 100755 --- a/mvc/Model.php +++ b/mvc/Model.php @@ -637,7 +637,7 @@ } //On fabrique la requete - $query = "INSERT INTO " . $table . "(" . implode(', ', $fieldNames) . ") VALUES(:" . implode(', :', $fieldNames) . ")"; + $query = "INSERT INTO " . $table . " (" . implode(', ', $fieldNames) . ") VALUES(:" . implode(', :', $fieldNames) . ")"; //On retourne le nombre de lignes insérées return $this->runQuery($query, $params, self::ROWCOUNT);