From 16aae8983104755f7db211e4488d2c5db7c698a1 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sun, 10 Dec 2017 20:36:33 +0100 Subject: [PATCH] BIG UPDATE: upgraded database version + configuration + added 'repo.admin' --- build/database/core/DatabaseDriver.php | 197 +++++++++++++++++++ build/database/core/Repo.php | 79 ++++++++ build/database/core/Repo_i.php | 18 ++ build/database/repo/admin.php | 250 +++++++++++++++++++++++++ config/database-driver.json | 16 ++ 5 files changed, 560 insertions(+) create mode 100755 build/database/core/DatabaseDriver.php create mode 100644 build/database/core/Repo.php create mode 100644 build/database/core/Repo_i.php create mode 100644 build/database/repo/admin.php create mode 100755 config/database-driver.json diff --git a/build/database/core/DatabaseDriver.php b/build/database/core/DatabaseDriver.php new file mode 100755 index 0000000..83007eb --- /dev/null +++ b/build/database/core/DatabaseDriver.php @@ -0,0 +1,197 @@ + Database Server's host + * @dbname Database name + * @username Database username + * @password Database password + * + */ + private function __construct($host, $dbname, $username, $password){ + /* (2) Stores configuration */ + $this->host = $host; + $this->dbname = $dbname; + $this->username = $username; + $this->password = $password; + + try{ + + $this->pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname, $this->username, $this->password, [ + \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, + \PDO::ATTR_TIMEOUT => 5 + ]); + + // On signale que tout s'est bien passe + $this->error = new Error(Err::Success); + + }catch(Exception $e){ + // On signale qu'il y a une erreur + $this->error = new Error(Err::PDOConnection); + } + } + + + + /************************************************ + **** Multiton Management (static) **** + ************************************************/ + + /* ADDS A NEW CONNECTION + * + * @label [optional] Database Label + * + * @return status If added successfully + * + */ + private static function add($label=null){ + $conf = self::conf(); + + /* [1] Default values + =========================================================*/ + /* (1) If label isn't given */ + is_null($label) && ($label = 'default'); + + /* (2) If label and no path */ + if( $label !== 'default' && !isset($conf[$label]) ) + return false; + + + /* [3] Instanciates the driver + =========================================================*/ + try{ + + /* (1) If local -> instanciates with local configuration */ + // if( !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') ) + self::$instance[$label] = new DatabaseDriver($conf[$label]['local']['host'], $conf[$label]['local']['dbname'], $conf[$label]['local']['user'], $conf[$label]['local']['password']); + /* (2) If Remote -> instanciates with Remote configuration */ + // else + // self::$instance[$label] = new DatabaseDriver($conf[$label]['remote']['host'], $conf[$label]['remote']['dbname'], $conf[$label]['remote']['user'], $conf[$label]['remote']['password']); + + return true; + + }catch(\Exception $e){ + + /* (3) If fails */ + return false; + + } + + } + + + /* GET A DATABASE DRIVER INSTANCE + * + * @label [optional] Driver's label + * + * @return driver Multiton + * + */ + public static function get($label=null){ + $conf = self::conf(); + + /* [1] Checks arguments + =========================================================*/ + /* (1) Label default value */ + is_null($label) && ($label = 'default'); + + /* (2) If no label, or unknown label */ + if( is_null($label) || !isset(self::$instance[$label]) ){ + + /* (2.1) Try to add the configuration if exists */ + if( isset($conf[$label]) ){ + self::add($label); + return self::get($label); + } + + + throw new \Exception('Database @label is incorrect.'); + } + + + /* [2] Returns instance + =========================================================*/ + return self::$instance[$label]; + } + + + /** retourne la connection statique + * @param null $label + * @return \PDO + */ + public static function getPDO($label=null){ + $instance = self::get($label); + + return $instance->pdo; + } + + + public function pdo(){ + return $this->pdo; + } + + + public function getConfig(){ + return [ + 'host' => $this->host, + 'dbname' => $this->dbname, + 'username' => $this->username + ]; + } + + + + } +?> diff --git a/build/database/core/Repo.php b/build/database/core/Repo.php new file mode 100644 index 0000000..d591b3d --- /dev/null +++ b/build/database/core/Repo.php @@ -0,0 +1,79 @@ +pdo()); + + + /* (3) Check if the method exists */ + if( !\method_exists($instance, $method) ) + throw new \Exception("Repo '$repo' has no public method '$method'"); + + /* (4) Fetch response (send arguments as well) */ + $response = call_user_func_array([$instance, $method], array_slice(func_get_args(), 2)); + + /* (5) Call post-script */ + $instance = null; + + /* (6) Dispatch response */ + return $response; + + } + + + + + } \ No newline at end of file diff --git a/build/database/core/Repo_i.php b/build/database/core/Repo_i.php new file mode 100644 index 0000000..5b9aad5 --- /dev/null +++ b/build/database/core/Repo_i.php @@ -0,0 +1,18 @@ +pdo = $pdo; + + } + + } \ No newline at end of file diff --git a/build/database/repo/admin.php b/build/database/repo/admin.php new file mode 100644 index 0000000..0053474 --- /dev/null +++ b/build/database/repo/admin.php @@ -0,0 +1,250 @@ + The admin list + * FALSE on error + * + ---------------------------------------------------------*/ + public function getAll(){ + + /* (1) Statement */ + $st = $this->pdo->query("SELECT * FROM `admin` ORDER BY `username` ASC"); + + /* (2) Fetched data */ + return $st->fetchAll(); + + } + + + /* (2) Return a admin by its `id_admin` + * + * @id_admin The admin UID + * + * @return admin The admin if found + * FALSE on error + * + ---------------------------------------------------------*/ + public function getById(int $id_admin){ + + /* (1) Prepare Statement */ + $pst = $this->pdo->prepare("SELECT * FROM `admin` WHERE `id_admin` = :id_admin LIMIT 1"); + + /* (2) Bind variables */ + $pst->bindParam(':id_admin', $id_admin, \PDO::PARAM_INT); + + /* (3) Execute */ + if( !$pst->execute() ) return false; // if error -> send FALSE + + /* (4) Fetched data */ + return $pst->fetch(); + + } + + + /* (3) Return a admin by its `mail` + * + * @mail The admin mail address + * + * @return admin The admin if found + * FALSE on error + * + ---------------------------------------------------------*/ + public function getByMail(String $mail){ + + /* (1) Prepare Statement */ + $pst = $this->pdo->prepare("SELECT * FROM `admin` WHERE `mail` = :mail LIMIT 1"); + + /* (2) Bind variables */ + $pst->bindParam(':mail', $mail, \PDO::PARAM_STR, 50); + + /* (3) Execute */ + if( !$pst->execute() ) return false; // if error -> send FALSE + + /* (4) Fetched data */ + return $pst->fetch(); + + } + + + /* (4) Return a admin by its `username` + * + * @username The admin username + * + * @return admin The admin if found + * FALSE on error + * + ---------------------------------------------------------*/ + public function getByUsername(String $username){ + + /* (1) Prepare Statement */ + $pst = $this->pdo->prepare("SELECT * FROM `admin` WHERE `username` = :username LIMIT 1"); + + /* (2) Bind variables */ + $pst->bindParam(':username', $username, \PDO::PARAM_STR, 20); + + /* (3) Execute */ + if( !$pst->execute() ) return false; // if error -> send FALSE + + /* (4) Fetched data */ + return $pst->fetch(); + + } + + + /* (5) Return a admin by its `token` + * + * @token The admin token + * + * @return admin The admin if found + * FALSE on error + * + ---------------------------------------------------------*/ + public function getByToken(String $token){ + + /* (1) Prepare Statement */ + $pst = $this->pdo->prepare("SELECT * FROM `admin` WHERE `token` is not NULL AND `token` = :token LIMIT 1"); + + /* (2) Bind variables */ + $pst->bindParam(':token', $token, \PDO::PARAM_STR, 128); + + /* (3) Execute */ + if( !$pst->execute() ) return false; // if error -> send FALSE + + /* (4) Fetched data */ + return $pst->fetch(); + + } + + + /* (6) Check the password of a admin + * + * @id_admin The admin UID + * @password The password to test + * + * @return valid Whether the password is valid or not + * + ---------------------------------------------------------*/ + public function checkPassword(int $id_admin, String $password){ + + /* (1) Hash the password */ + $hash = \secure_hash($password, $id_admin, 'admin-pass'); + + /* (2) Prepare Statement */ + $pst = $this->pdo->prepare("SELECT * FROM `admin` WHERE `id_admin` = :id_admin AND `pass` = :pass LIMIT 1"); + + /* (3) Bind variables */ + $pst->bindParam(':id_admin', $id_admin, \PDO::PARAM_INT); + $pst->bindParam(':pass', $hash, \PDO::PARAM_STR, 128); + + /* (4) Execute */ + if( !$pst->execute() ) return false; // if error -> send FALSE + + /* (5) If no data -> means invalid password */ + if( !is_array($pst->fetch()) ) + return false; + + /* (6) If here -> means password is ok */ + return true; + + } + + + /* (6) Set the password for a admin + * + * @id_admin The admin UID + * @password The password to set + * + * @return set Whether the password has been set or not + * + ---------------------------------------------------------*/ + public function setPassword(int $id_admin, String $password){ + + /* (1) Hash the password */ + $hash = \secure_hash($password, $id_admin, 'admin-pass'); + + /* (2) Prepare Statement */ + $pst = $this->pdo->prepare("UPDATE `admin` SET `pass` = :pass WHERE `id_admin` = :id_admin"); + + /* (3) Bind variables */ + $pst->bindParam(':pass', $hash, \PDO::PARAM_STR, 128); + $pst->bindParam(':id_admin', $id_admin, \PDO::PARAM_INT); + + /* (4) Execute -> dispatch status */ + return $pst->execute(); + + } + + /* (7) Creates a new admin + * + * @username The username (must be unique) + * @mail The mail address (must be unique) + * @password The password + * + * @return id_created UID of the created admin + * FALSE on error + * + ---------------------------------------------------------*/ + public function create(String $username, String $mail, String $password){ + + + /* (1) Check @username + @mail are unique + ---------------------------------------------------------*/ + /* (1) If @username already exists -> abort */ + if( is_array($this->getByUsername($username)) ) + return false; + + /* (2) If @mail already exists -> abort */ + if( is_array($this->getByMail($mail)) ) + return false; + + + + /* (2) Create the admin (without password) + ---------------------------------------------------------*/ + /* (1) Create a random token */ + $token = \secure_hash(uniqid(), 'admin-token'); + + /* (2) Prepare Statement */ + $pst = $this->pdo->prepare("INSERT INTO `admin`(`id_admin`, `username`, `mail`, `pass`, `token`) VALUES(DEFAULT, :username, :mail, NULL, :token)"); + + /* (3) Bind variables */ + $pst->bindParam(':username', $username, \PDO::PARAM_STR, 20); + $pst->bindParam(':mail', $mail, \PDO::PARAM_STR, 50); + $pst->bindParam(':token', $token, \PDO::PARAM_STR, 128); + + /* (4) Execute -> if error return FALSE */ + if( !$pst->execute() ) return false; + + + /* (2) Set the password (needed @id_admin) + ---------------------------------------------------------*/ + /* (1) Get last inserted id */ + $fetch_admin = $this->getByUsername($username); + + /* (2) If nothing found -> error */ + if( !is_array($fetch_admin) || !isset($fetch_admin['id_admin']) || !is_numeric($fetch_admin['id_admin']) ) + return false; + + /* (3) Extract @id_admin */ + $id_admin = intval($fetch_admin['id_admin']); + + /* (4) Repo self call */ + if( !$this->setPassword($id_admin, $password) ) + return false; + + /* (5) Return @id_admin */ + return $id_admin; + + } + + + + + } \ No newline at end of file diff --git a/config/database-driver.json b/config/database-driver.json new file mode 100755 index 0000000..da74338 --- /dev/null +++ b/config/database-driver.json @@ -0,0 +1,16 @@ +{ + "default": { + "local": { + "host" : "localhost", + "dbname" : "prod-releaser", + "user" : "prod-releaser-php", + "password" : "a64e9fede92c55932ce82d77891f77a1f015a9f1" + }, + "remote": { + "host" : "db_remote_host", + "dbname" : "db_remote_name", + "user" : "db_remote_user", + "password" : "db_remote_password" + } + } +}