117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
namespace nur\sery\file\csv;
 | 
						|
 | 
						|
use nur\sery\A;
 | 
						|
use nur\sery\php\time\Date;
 | 
						|
use nur\sery\php\time\DateTime;
 | 
						|
 | 
						|
abstract class AbstractReader  implements IReader {
 | 
						|
  const SCHEMA = null;
 | 
						|
 | 
						|
  const HEADERS = null;
 | 
						|
 | 
						|
  /** @var bool faut-il utiliser les en-têtes pour retourner des tableaux associatifs? */
 | 
						|
  const COOk_ROWS = true;
 | 
						|
 | 
						|
  /** @var ?string nom du fichier depuis lequel lire */
 | 
						|
  const INPUT = null;
 | 
						|
 | 
						|
  /** @var bool faut-il trimmer le champ avant de le traiter? */
 | 
						|
  const TRIM = true;
 | 
						|
 | 
						|
  /** @var bool faut-il considérer les chaines vides comme null? */
 | 
						|
  const PARSE_EMPTY_AS_NULL = true;
 | 
						|
 | 
						|
  /**
 | 
						|
   * @var bool faut-il forcer le type numérique pour une chaine numérique?
 | 
						|
   * si false, ne forcer le type numérique que si la chaine ne commence pas zéro
 | 
						|
   * i.e "06" est une chaine, alors "63" est un nombre
 | 
						|
   */
 | 
						|
  const PARSE_NUMERIC = false;
 | 
						|
 | 
						|
  /**
 | 
						|
   * @var bool faut-il forcer le type {@link Date} ou {@link DateTime} pour une
 | 
						|
   * chaine au bon format?
 | 
						|
   */
 | 
						|
  const PARSE_DATE = true;
 | 
						|
 | 
						|
  function __construct($input, ?array $params=null) {
 | 
						|
    if ($input !== null) $params["input"] = $input;
 | 
						|
    #
 | 
						|
    $this->schema = $params["schema"] ?? static::SCHEMA;
 | 
						|
    $this->headers = $params["headers"] ?? static::HEADERS;
 | 
						|
    $this->cookRows = $params["cook_rows"] ?? static::COOk_ROWS;
 | 
						|
    $this->input = $params["input"] ?? static::INPUT;
 | 
						|
    $this->trim = boolval($params["trim"] ?? static::TRIM);
 | 
						|
    $this->parseEmptyAsNull = boolval($params["empty_as_null"] ?? static::PARSE_EMPTY_AS_NULL);
 | 
						|
    $this->parseNumeric = boolval($params["parse_numeric"] ?? static::PARSE_NUMERIC);
 | 
						|
    $this->parseDate = boolval($params["parse_date"] ?? static::PARSE_DATE);
 | 
						|
  }
 | 
						|
 | 
						|
  protected ?array $schema;
 | 
						|
 | 
						|
  protected ?array $headers;
 | 
						|
 | 
						|
  protected bool $cookRows;
 | 
						|
 | 
						|
  protected $input;
 | 
						|
 | 
						|
  protected bool $trim;
 | 
						|
 | 
						|
  protected bool $parseEmptyAsNull;
 | 
						|
 | 
						|
  protected bool $parseNumeric;
 | 
						|
 | 
						|
  protected bool $parseDate;
 | 
						|
 | 
						|
  protected int $isrc = 0, $idest = 0;
 | 
						|
 | 
						|
  protected function cookRow(array &$row): bool {
 | 
						|
    if (!$this->cookRows) return true;
 | 
						|
    if ($this->isrc == 0) {
 | 
						|
      # ligne d'en-tête
 | 
						|
      $headers = $this->headers;
 | 
						|
      if ($headers === null) {
 | 
						|
        if ($this->schema === null) $headers = null;
 | 
						|
        else $headers = array_keys($this->schema);
 | 
						|
        if ($headers === null) $headers = $row;
 | 
						|
        $this->headers = $headers;
 | 
						|
      }
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    A::ensure_size($row, count($this->headers));
 | 
						|
    $row = array_combine($this->headers, $row);
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  protected function verifixCol(&$col): void {
 | 
						|
    if ($this->trim && is_string($col)) {
 | 
						|
      $col = trim($col);
 | 
						|
    }
 | 
						|
    if ($this->parseEmptyAsNull && $col === "") {
 | 
						|
      # valeur vide --> null
 | 
						|
      $col = null;
 | 
						|
    }
 | 
						|
    if (!is_string($col)) return;
 | 
						|
    if ($this->parseDate) {
 | 
						|
      if (DateTime::isa_datetime($col, true)) {
 | 
						|
        # datetime
 | 
						|
        $col = new DateTime($col);
 | 
						|
      } elseif (DateTime::isa_date($col, true)) {
 | 
						|
        # date
 | 
						|
        $col = new Date($col);
 | 
						|
      }
 | 
						|
      if (!is_string($col)) return;
 | 
						|
    }
 | 
						|
    $parseNumeric = $this->parseNumeric || substr($col, 0, 1) !== "0";
 | 
						|
    if ($parseNumeric) {
 | 
						|
      $tmp = str_replace(",", ".", $col);
 | 
						|
      $float = strpos($tmp, ".") !== false;
 | 
						|
      if (is_numeric($tmp)) {
 | 
						|
        if ($float) $col = floatval($tmp);
 | 
						|
        else $col = intval($tmp);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |