SMMP/manager/ORM.php

315 lines
7.8 KiB
PHP
Raw Normal View History

2016-07-21 19:12:53 +00:00
<?php
use \manager\Database;
use \manager\ManagerError;
namespace manager;
// CLASSE MAITRE
class ORM{
// Constantes
const UNIQUE = 0x0d3f378e6a8;
// Informations de l'utilisateur
private $data;
public $error;
// Informations de la base de données
private $schema;
private static $database = 'stefproject';
/* CONSTRUCTEUR DE LA CLASSE
*
* @table<String> Nom de la table à selectionner
*
* @return this<ORM> Retourne une instance de l'ORM
*
*/
public function __construct($table_name){
/* [0] Initialisation des attributs
=========================================================*/
$this->init();
/* [1] On vérifie que la table existe
=========================================================*/
/* (1) Requête */
$checkTable = Database::getPDO()->query("SHOW tables FROM ".self::$database);
$checkTableResult = Database::delNumeric( $checkTable->fetchAll() );
/* (2) On met en forme les données */
$tables = [];
foreach($checkTableResult as $table)
$tables[] = $table['Tables_in_'.self::$database];
/* (3) Si n'existe pas, on renvoie une erreur */
if( !in_array($table_name, $tables) ){
$this->error = ManagerError::UnknownTable;
return;
}
/* (4) On enregistre les données */
$this->data['table'] = $table_name;
/* [2] Si la table existe, on récupère ses données
=========================================================*/
/* (1) On récupère les colonnes */
$getColumns = Database::getPDO()->query("SHOW columns FROM ".self::$database.'.'.$table_name);
$columnsResult = Database::delNumeric( $getColumns->fetchAll() );
/* (2) On met en forme les données */
$columns = [];
foreach($columnsResult as $col){
// On formatte le type //
$type = $col['Type'];
if( preg_match('/^(int|varchar|text)/i', $type, $m) )
$type = $m[1];
// On ajoute la colonne //
$columns[$col['Field']] = [
'type' => $type,
'primary' => $col['Key'] == 'PRI'
];
}
/* (3) Si on trouve rien, on envoie une erreur */
if( !is_array($columns) || count($columns) == 0 ){
$this->error = ManagerError::UnknownTable;
return;
}
/* (4) On enregistre les colonnes */
$this->schema['columns'] = $columns;
}
/* GESTION DES GETTERS dynamiques
*
*
*/
public function __call($method, $params){
// Si $this->data['table'] NULL
if( is_null($this->data['table']) ) return false;
/* [1] Getters dynamiques
=========================================================*/
if( preg_match('/^get(.+)$/', $method, $matches) )
return $this->dynamicGetter($matches[1], $params);
}
/* GETTERS DYNAMIQUES
*
* @keywords<String> Nom du getter du type 'getAll' ou 'getX' avec 'X' une colonne de la table en question
* @params<Array> Liste des arguments, $args[0] est la valeur du getter (sauf pour 'getAll')
*
* @return lines<Array> Retourne le résultat du fetchAll()
*
*/
private function dynamicGetter($selector, $params){
/* [3] On vérifie la requête
=========================================================*/
/* (1) On formatte la requête 'MyNewColumn' -> 'my_new_column' */
$column_name = '';
// On retire le By.... s'il y est
if( preg_match('/^By(.+)$/', $selector, $m) ) $selector = $m[1];
// On transforme les majuscules en _
for( $l = 0 ; $l < strlen($selector) ; $l++ ){
$letter = $selector[$l];
// Si la lettre est en majuscule mais que c'est pas la première
if( strtoupper($letter) == $letter && $l > 0 )
$column_name .= '_';
$column_name .= strtolower($letter);
}
/* (2) On trouve le type de getter */
$getAll = $column_name == 'all'; // Si 'getAll'
$getById = $column_name == 'id'; // Si 'getById'
$getSomething = count($params) > 0 && array_key_exists($column_name, $this->schema['columns']); // Si 'getX', et 'X' dans la liste des colonnes
/* (3) Et le type de résultat attendu */
$fetchUnique = $params[count($params)-1] == self::UNIQUE;
/* (4) Si ni 'getAll' ni 'getSomething' -> erreur */
if( !$getById && !$getAll && !$getSomething ) return false;
/* [4] On rédige la requête
=========================================================*/
$getRequestString = 'SELECT * FROM '.$this->data['table'];
/* (1) getById
---------------------------------------------------------*/
if( $getById ){
/* (1) On récupère les 'champs' formant la CLÉ PRIMAIRE */
$primary = [];
foreach($this->schema['columns'] as $k=>$v)
if( $v['primary'] ) $primary[] = $k;
/* (2) S'il manque un paramètre, on retourne une erreur */
if( count($params) < count($primary) )
return false;
/* (3) On ajoute les conditions pour chaque clé primaire */
foreach($primary as $i=>$primary_key)
if( $i == 0 ) $getRequestString .= ' WHERE '.$primary_key.' = :primary'.$i;
else $getRequestString .= ' AND '.$primary_key.' = :primary'.$i;
/* (2) get{Attribut}
---------------------------------------------------------*/
}else if( $getSomething )
$getRequestString .= ' WHERE '.$column_name.' = :value';
/* (3) getAll
---------------------------------------------------------*/
// Aucune condition
/* (4) Ordre de selection
---------------------------------------------------------*/
$getRequestString .= ' ORDER BY 1 ASC';
/* [5] On prépare la requête
=========================================================*/
$getRequest = Database::getPDO()->prepare($getRequestString);
/* [6] On exécute la requête
=========================================================*/
/* (1) getById
---------------------------------------------------------*/
if( $getById ){
/* (1) On ajoute les variables pour chaque valeur donnée */
$pdo_vars = [];
foreach($primary as $i=>$primary_key)
$pdo_vars[':primary'.$i] = $params[$i];
/* (2) On exécute la requête */
$getRequest->execute( $pdo_vars );
/* (2) get{Attribut}
---------------------------------------------------------*/
}else
// Valeur unique
$getRequest->execute([
':value' => $getSomething ? $params[0] : null
]);
/* [7] On récupère le résultat
=========================================================*/
/* (1) getById -> Réponse unique */
if( $getById ){
$result = $getRequest->fetch();
if( $result === false )
if( $fetchUnique ) return null;
else return [];
else
if( $fetchUnique ) return Database::delNumeric($result, true);
else return [Database::delNumeric($result, true)];
/* (2) Autre -> Réponse multiple */
}else{
$result = Database::delNumeric( $getRequest->fetchAll() );
if( $fetchUnique )
if( count($result) < 1 ) return null;
else return $result[0];
else return $result;
}
}
/* EFFACE/INITIALISE LES DONNEES DE L'ORM
*
*/
private function init(){
$this->data = [];
$this->schema = [];
}
};
// // USE CASE :: ACCESS TABLE
// ORM::Table = ORM::Table('user');
//
// // USE CASE :: getBy{ATTRIBUTE}
// ORM::Row = ORM::Table->getByUsername('someUsername'); // ORM_FETCH by default
// ORM::Row = ORM::Table->getByUsername('someUsername', ORM_FETCH);
// ORM::Column = ORM::Table->getByUsername('someUsername', ORM_FETCHALL);
//
// // USE CASE :: getById -> primary key(s)
// ORM::Row = ORM::Table->getById(5, 7); // because PRIMARY KEY is composed by '5' and '7'
//
// // USE CASE :: getAll
// ORM::Column = ORM::Table->getAll();
//
// // USE CASE :: select(FIELD)
// mixed = ORM::Row->select('username');
//
// // USE CASE :: select(FIELD1, FIELD2, ...)
// mixed = ORM::Row->select('id_user', 'username');
?>