134 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nulib\file\tab;
 | |
| 
 | |
| use nulib\A;
 | |
| use nulib\php\time\Date;
 | |
| use nulib\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 USE_HEADERS = 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 EMPTY_AS_NULL = true;
 | |
| 
 | |
|   /**
 | |
|    * @var bool ne pas essayer de deviner le format des données: les laisser au
 | |
|    * format chaine.
 | |
|    */
 | |
|   const PARSE_NONE = false;
 | |
| 
 | |
|   /**
 | |
|    * @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 par
 | |
|    * zéro i.e "06" est une chaine, alors "63" est un nombre
 | |
|    *
 | |
|    * ce paramètre est ignoré si PARSE_NONE == true
 | |
|    */
 | |
|   const PARSE_NUMERIC = false;
 | |
| 
 | |
|   /**
 | |
|    * @var bool faut-il forcer le type {@link Date} ou {@link DateTime} pour une
 | |
|    * chaine au bon format?
 | |
|    *
 | |
|    * ce paramètre est ignoré si PARSE_NONE == true
 | |
|    */
 | |
|   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->useHeaders = $params["use_headers"] ?? static::USE_HEADERS;
 | |
|     $this->input = $params["input"] ?? static::INPUT;
 | |
|     $this->skip = $params["skip"] ?? 0;
 | |
|     $this->trim = boolval($params["trim"] ?? static::TRIM);
 | |
|     $this->emptyAsNull = boolval($params["empty_as_null"] ?? static::EMPTY_AS_NULL);
 | |
|     $this->parseNone = boolval($params["parse_none"] ?? static::PARSE_NONE);
 | |
|     $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 $useHeaders;
 | |
| 
 | |
|   protected $input;
 | |
| 
 | |
|   protected int $skip;
 | |
| 
 | |
|   protected bool $trim;
 | |
| 
 | |
|   protected bool $emptyAsNull;
 | |
| 
 | |
|   protected bool $parseNone;
 | |
| 
 | |
|   protected bool $parseNumeric;
 | |
| 
 | |
|   protected bool $parseDate;
 | |
| 
 | |
|   protected int $isrc = 0, $idest = 0;
 | |
| 
 | |
|   protected function cookRow(array &$row): bool {
 | |
|     if (!$this->useHeaders) return true;
 | |
|     if ($this->skip > 0) {
 | |
|       $this->skip--;
 | |
|       return false;
 | |
|     }
 | |
|     if ($this->headers === null) {
 | |
|       # ligne d'en-tête
 | |
|       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->emptyAsNull && $col === "") {
 | |
|       # valeur vide --> null
 | |
|       $col = null;
 | |
|     }
 | |
|     if (!is_string($col) || $this->parseNone) 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);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 |