From 28ee595406e4f98c7a155d801c5a0bef4eee6c50 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Thu, 21 Jul 2016 22:05:30 +0200 Subject: [PATCH] ORM getBy{...} + select() fonctionnel --- manager/ORM.php | 314 ------------------------------------------ manager/ORM/Row.php | 2 +- manager/ORM/Rows.php | 101 ++++++++++++-- manager/ORM/Table.php | 116 ++++++++++++++++ test/automate.php | 10 +- 5 files changed, 215 insertions(+), 328 deletions(-) delete mode 100644 manager/ORM.php create mode 100644 manager/ORM/Table.php diff --git a/manager/ORM.php b/manager/ORM.php deleted file mode 100644 index b974957..0000000 --- a/manager/ORM.php +++ /dev/null @@ -1,314 +0,0 @@ - Nom de la table à selectionner - * - * @return this 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 Nom du getter du type 'getAll' ou 'getX' avec 'X' une colonne de la table en question - * @params Liste des arguments, $args[0] est la valeur du getter (sauf pour 'getAll') - * - * @return lines 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'); -?> diff --git a/manager/ORM/Row.php b/manager/ORM/Row.php index cfa740b..bd92050 100644 --- a/manager/ORM/Row.php +++ b/manager/ORM/Row.php @@ -1,6 +1,6 @@ schema = $schema; + + /* (2) On initialise les conditions */ + $this->where = []; } @@ -35,12 +40,17 @@ * */ public function getById($primary){ + /* [0] Vérification des paramètres + =========================================================*/ + if( $primary == null ) + return $this; + /* [1] On récupère les clés primaires =========================================================*/ $keys = []; foreach($this->schema['columns'] as $k=>$v) - $keys[] = $k; + if( $v['primary'] ) $keys[] = $k; /* [2] Si clé simple @@ -48,15 +58,15 @@ if( count($keys) == 1 ){ /* (1) Si type INT et pas numérique */ - if( $this->schema['columns'][$keys]['type'] == 'int' && !is_numeric($primary[0]) ) + if( $this->schema['columns'][$keys[0]]['type'] == 'int' && !is_numeric($primary) ) return $this; /* (2) Si type STRING et pas string */ - if( $this->schema['columns'][$keys]['type'] == 'text' && !is_string($primary[0]) ) + if( $this->schema['columns'][$keys[0]]['type'] == 'text' && !is_string($primary) ) return $this; /* (3) Si type OK, on enregistre la condition */ - $this->where[$keys[0]] = $primary[0]; + $this->where[$keys[0]] = $primary; /* [3] Si clé composée @@ -66,7 +76,7 @@ $defaultWhere = $this->where; /* (1) Pour chaque clé, On vérifie les TYPES */ - foreach($key as $i=>$key){ + foreach($keys as $i=>$key){ /* (2) Si type INT et pas numérique */ if( $this->schema['columns'][$key]['type'] == 'int' && !is_numeric($primary[$i]) ){ @@ -148,10 +158,13 @@ if( $this->schema['columns'][$column_name]['type'] == 'text' && !is_string($a[0]) ) return $this; - /* (4) Si type OK, on enregistre la condition */ - $this->where[$keys[0]] = $a[0]; + + /* [3] Si type OK, on enregistre la condition + =========================================================*/ + $this->where[$column_name] = $a[0]; + return $this; } @@ -166,15 +179,79 @@ * @return data Valeur du champ sélectionné (si 1 seul champ) * */ - public function select($fields){ + public function select($fields=[]){ + /* [0] On formatte les champs + =========================================================*/ + /* (1) On met en tableau quoi qu'il en soit */ + $fields = is_array($fields) ? $fields : [$fields]; + /* (2) On vérifie que chaque champ existe, sinon on le retire */ + foreach($fields as $f=>$field) + if( !array_key_exists($field, $this->schema['columns']) ) + unset($fields[$f]); + + /* (3) Permet d'avoir les indices de 0 à count-1 */ + sort($fields); + + + + /* [1] On rédige la requête + =========================================================*/ + /* (1) On initialise la requête */ + $requestS = "SELECT "; + + /* (2) Si aucun champ, on sélectionne tous les champs */ + if( count($fields) == 0 ) + $requestS .= "* "; + + /* (3) Sinon, on sélectionne les champs que l'on veut */ + else + foreach($fields as $f=>$field) + if( $f == 0 ) $requestS .= $field; + else $requestS .= ', '.$field; + + + /* (4) Clause FROM */ + $requestS .= "\nFROM ".$this->schema['table']."\n"; + + + /* (5) On ajoute les conditions */ + $c = 0; + foreach($this->where as $field=>$value){ + if( $c == 0 ) $requestS .= ' WHERE '.$field.' = :'.$field."\n"; + else $requestS .= ' AND '.$field.' = :'.$field."\n"; + + $c++; + } + + /* (6) On prépare la requête */ + $request = Database::getPDO()->prepare($requestS); + + + + /* [5] On exécute la requête et 'bind' les paramètres + =========================================================*/ + /* (1) On bind tous les paramètres */ + $binded = []; + + foreach($this->where as $field=>$value) + $binded[':'.$field] = $value; + + /* (2) On exécute la requête */ + $request->execute($binded); + + + + /* [6] On retourne le résultat + =========================================================*/ + return Database::delNumeric( $request->fetchAll() ); } - /* MODIFIE DES ENTREES + /* MODIFIE DES ENTREES * * @updates Tableau associatif contenant les nouvelles valeurs * diff --git a/manager/ORM/Table.php b/manager/ORM/Table.php new file mode 100644 index 0000000..d36352d --- /dev/null +++ b/manager/ORM/Table.php @@ -0,0 +1,116 @@ + Nom de la table à selectionner + * + * @return this Retourne une instance de l'ORM + * + */ + public static function get($table_name){ + /* [0] Initialisation des attributs + =========================================================*/ + $schema = [ + 'database' => self::$database, + 'table' => null, + 'columns' => null + ]; + + + /* [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) ) + return null; + + /* (4) On enregistre les données */ + $schema['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] == 'int') ? 'int' : 'text'; + + // 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 ) + return null; + + /* (4) On enregistre les colonnes */ + $schema['columns'] = $columns; + + + + /* [3] On renvoie une instance de 'Rows' + =========================================================*/ + return new Rows($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'); +?> diff --git a/test/automate.php b/test/automate.php index 0d46019..2c96f29 100755 --- a/test/automate.php +++ b/test/automate.php @@ -7,6 +7,10 @@ use \manager\ManagerError; use \manager\Repo; use \manager\Database; + + + use \manager\ORM\Table; + use \manager\ORM\Rows; use \manager\ORM\Row; debug(); @@ -338,8 +342,12 @@ debug(); - $userFetch = new Row('user'); + $userTable = + Table::get('user') + ->getByIdWarehouse(7) + ->select(['mail', 'username', 'firstname']); + var_dump($userTable); ?>