BIG UPDATE: upgraded database version + configuration + added 'repo.admin'

This commit is contained in:
xdrm-brackets 2017-12-10 20:36:33 +01:00
parent 6379837deb
commit 16aae89831
5 changed files with 560 additions and 0 deletions

View File

@ -0,0 +1,197 @@
<?php
/**************************
* DatabaseDriver *
* 08-04-2016 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace database\core;
use \error\core\Error;
use \error\core\Err;
class DatabaseDriver{
/* STATIC ATTRIBUTES */
private static function conf(){
// YOUR CONFIGURATION BEHIND
$path = __CONFIG__.'/database-driver.json';
/* (1) Checks the file */
if( !is_file($path) )
return [];
/* (2) Checks json */
$parsed = json_decode( file_get_contents($path), true );
if( !is_array($parsed) )
return [];
/* (3) Returns configuration */
return $parsed;
}
private static $path; // Databases configurations files
private static $config; // PDO configurations
private static $instance = []; // Database driver instance list
public $error;
/* ATTRIBUTES */
private $host;
private $dbname;
private $username;
private $password;
private $pdo;
/* CONSTRUCTOR OF A DATABASE DRIVER
*
* @host<String> Database Server's host
* @dbname<String> Database name
* @username<String> Database username
* @password<String> 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<String> [optional] Database Label
*
* @return status<Boolean> 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<String> [optional] Driver's label
*
* @return driver<Database> 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
];
}
}
?>

View File

@ -0,0 +1,79 @@
<?php
/**************************
* Repo *
* 24-11-2017 *
***************************
* Designed & Developed by *
* xdrm-brackets *
***************************
* https://xdrm.io/ *
**************************/
namespace database\core;
use \error\core\Error;
use \error\core\Err;
class Repo{
/* (1) Driver
---------------------------------------------------------*/
private static $driver = null;
public static function setDriver(DatabaseDriver $driver){ self::$driver = $driver; }
public static function request(String $repo=null, String $method=null){
/* (1) Check arguments
---------------------------------------------------------*/
/* (1) Check @repo */
if( !is_string($repo) || strlen($repo) < 1 )
throw new \Exception("@repo is not a non-empty string");
/* (2) Check @method */
if( !is_string($method) || strlen($method) < 1 )
throw new \Exception("@method is not a non-empty string");
/* (3) Check class path */
$class_path = "\\database\\repo\\$repo";
if( !\class_exists($class_path) )
throw new \Exception("Repo class '$class_path' cannot be found");
/* (2) Call the method
---------------------------------------------------------*/
/* (1) Create the instance (pre-script) */
$instance = new $class_path();
/* (2) Check extends Repo_i */
if( !( $instance instanceof Repo_i ) )
throw new \Exception("Repo class '$class_path' must extends Repo_i");
/* (3) Bind pdo instance */
\call_user_func([$instance, 'setPDO'], self::$driver->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;
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace database\core;
class Repo_i{
/**
* @var \PDO
*/
protected $pdo = null;
public function setPDO( \PDO $pdo){
$this->pdo = $pdo;
}
}

View File

@ -0,0 +1,250 @@
<?php
namespace database\repo;
use \database\core\Repo_i;
class admin extends Repo_i{
/* (1) Return all admins in database
*
* @return admins<array> 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<int> The admin UID
*
* @return admin<array> 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<String> The admin mail address
*
* @return admin<array> 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<String> The admin username
*
* @return admin<array> 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<String> The admin token
*
* @return admin<array> 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<String> The admin UID
* @password<String> The password to test
*
* @return valid<bool> 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<String> The admin UID
* @password<String> The password to set
*
* @return set<bool> 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<String> The username (must be unique)
* @mail<String> The mail address (must be unique)
* @password<String> The password
*
* @return id_created<int> 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;
}
}

16
config/database-driver.json Executable file
View File

@ -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"
}
}
}