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);
 | 
						|
  }
 | 
						|
}
 |