135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nur\m\base;
 | |
| 
 | |
| use nur\A;
 | |
| use nur\b\ValueException;
 | |
| use nur\iter;
 | |
| use nur\m\IConn;
 | |
| 
 | |
| abstract class EntityManager {
 | |
|   const TABLE_NAME = null;
 | |
|   const PK_KEY = null;
 | |
|   const PK_AUTO = null;
 | |
| 
 | |
|   /**
 | |
|    * retourner les champs de la clé primaire
 | |
|    * - soit une valeur chaine si c'est une clé simple
 | |
|    * - soit un tableau si c'est une clé composite 
 | |
|    */
 | |
|   protected static function get_pk_key($row, $pk_key=null) {
 | |
|     if ($pk_key === null) $pk_key = static::PK_KEY;
 | |
|     if (is_array($pk_key) && count($pk_key) == 1) $pk_key = iter::first($pk_key);
 | |
|     if ($pk_key === false) {
 | |
|       # si $pk_key est false, alors toute la ligne est une clé: prendre les noms
 | |
|       # des colonnes
 | |
|       $pk_key = array_keys(A::with($row));
 | |
|       if (is_array($pk_key) && count($pk_key) == 1) $pk_key = iter::first($pk_key);
 | |
|     }
 | |
|     return $pk_key;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Obtenir la valeur de la clé primaire d'une ligne.
 | |
|    *
 | |
|    * - Si $pk_key vaut false, considérer que la clé est l'ensemble des colonnes.
 | |
|    * - Si la clé est composite, retourner un tableau associatif avec toutes les
 | |
|    * valeurs
 | |
|    * - Sinon retourner uniquement la valeur de la clé.
 | |
|    */
 | |
|   protected static function get_pk_value($row, $pk_key=null) {
 | |
|     $pk_key = self::get_pk_key($row, $pk_key);
 | |
|     if (is_array($pk_key)) {
 | |
|       if (!is_array($row)) throw ValueException::invalid_value($row, "row");
 | |
|       $pk_value = [];
 | |
|       foreach ($pk_key as $col) {
 | |
|         $pk_value[$col] = A::get($row, $col);
 | |
|       }
 | |
|       return $pk_value;
 | |
|     } elseif (is_array($row)) {
 | |
|       return A::get($row, $pk_key);
 | |
|     } else {
 | |
|       return $row;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * obtenir un tableau bindings pour filtrer une table sur la valeur de la clé
 | |
|    * primaire
 | |
|    */
 | |
|   protected static function get_pk_bindings($row, $pk_key=null): array {
 | |
|     $pk_value = self::get_pk_value($row, $pk_key);
 | |
|     if (is_array($pk_value)) return $pk_value;
 | |
|     $pk_key = self::get_pk_key($row, $pk_key);
 | |
|     return [$pk_key => $pk_value];
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Obtenir la valeur de la clé primaire d'une ligne sous forme de chaine.
 | |
|    *
 | |
|    * Si la clé est composite, séparer chaque valeur par un tiret '-' pour faire
 | |
|    * une seule chaine.
 | |
|    */
 | |
|   protected static function get_pk_string($row, $pk_key=null): string {
 | |
|     $pk_value = self::get_pk_value($row, $pk_key);
 | |
|     if (is_array($pk_value)) $pk_string = implode("-", $pk_value);
 | |
|     else $pk_string = strval($pk_value);
 | |
|     return $pk_string;
 | |
|   }
 | |
| 
 | |
|   protected static function map_pks(iterable $rows, $pk_key=null): array {
 | |
|     $mapped_rows = [];
 | |
|     foreach ($rows as $row) {
 | |
|       $pk_string = self::get_pk_string($row, $pk_key);
 | |
|       $mapped_rows[$pk_string] = $row;
 | |
|     }
 | |
|     return $mapped_rows;
 | |
|   }
 | |
|   
 | |
|   protected static function sql_select_all(&$filter=null): string {
 | |
|     $sql = "select * from ". static::TABLE_NAME;
 | |
|     if ($filter !== null) {
 | |
|       if (!is_array($filter)) $filter = self::get_pk_bindings($filter);
 | |
|       $and = " where";
 | |
|       foreach ($filter as $col => $value) {
 | |
|         $sql .= "$and $col = :$col";
 | |
|         $and = " and";
 | |
|       }
 | |
|     }
 | |
|     return $sql;
 | |
|   }
 | |
| 
 | |
|   abstract static function conn(IConn $pdo=null): IConn;
 | |
| 
 | |
|   static function select_all($filter=null, $map_key=null): array {
 | |
|     $sql = self::sql_select_all($filter);
 | |
|     $rows = static::conn()->query($sql, $filter)->execute();
 | |
|     return self::map_pks($rows, $map_key);
 | |
|   }
 | |
| 
 | |
|   static function select_all_val(string $key, $filter=null): array {
 | |
|     $sql = self::sql_select_all($filter);
 | |
|     $rows = static::conn()->query($sql, $filter)->execute();
 | |
|     $vals = [];
 | |
|     foreach ($rows as $row) {
 | |
|       $vals[] = A::get($row, $key);
 | |
|     }
 | |
|     return $vals;
 | |
|   }
 | |
| 
 | |
|   static function select_first($filter=null, $default=null) {
 | |
|     $sql = self::sql_select_all($filter);
 | |
|     return static::conn()->query($sql, $filter)->first($default);
 | |
|   }
 | |
| 
 | |
|   static function select_first_val(string $key, $filter=null, $default=null) {
 | |
|     $sql = self::sql_select_all($filter);
 | |
|     $first = static::conn()->query($sql, $filter)->first($default);
 | |
|     return A::get($first, $key, $default);
 | |
|   }
 | |
| 
 | |
|   static function select_one($filter=null, $default=null, ?bool $rewind=null): array {
 | |
|     $sql = self::sql_select_all($filter);
 | |
|     return static::conn()->query($sql, $filter)->one($default, $rewind);
 | |
|   }
 | |
| }
 |