110 lines
3.0 KiB
PHP
110 lines
3.0 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 ?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->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 $input;
|
|
|
|
protected bool $trim;
|
|
|
|
protected bool $parseEmptyAsNull;
|
|
|
|
protected bool $parseNumeric;
|
|
|
|
protected bool $parseDate;
|
|
|
|
protected int $isrc = 0, $idest = 0;
|
|
|
|
protected function cook(array &$row): bool {
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|