From 7f378c6b8f0277e3a552a83c36603e083b7ed7d3 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sun, 16 Jun 2024 12:49:57 +0400 Subject: [PATCH] modifs.mineures sans commentaires --- src/cl.php | 23 +++++++++++ src/ext/spreadsheet/SpoutBuilder.php | 16 ++++---- src/file/csv/AbstractReader.php | 61 ++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 16 deletions(-) diff --git a/src/cl.php b/src/cl.php index 9e25be3..fe4ef52 100644 --- a/src/cl.php +++ b/src/cl.php @@ -196,6 +196,29 @@ class cl { return $dest; } + /** + * obtenir la liste des clés finalement obtenues après l'appel à + * {@link self::select()} avec le mapping spécifié + */ + static final function selected_keys(?array $mappings): array { + if ($mappings === null) return []; + $keys = []; + $index = 0; + foreach ($mappings as $to => $from) { + if ($to === $index) { + if ($from === false) continue; + elseif ($from === null) $keys[] = $index; + else $keys[] = $from; + $index++; + } elseif ($from === false) { + continue; + } else { + $keys[] = $to; + } + } + return $keys; + } + /** * méthode de convenance qui sélectionne certaines clés de $array avec * {@link self::select()} puis merge le tableau $merge au résultat. diff --git a/src/ext/spreadsheet/SpoutBuilder.php b/src/ext/spreadsheet/SpoutBuilder.php index 4fff5f9..e05bfba 100644 --- a/src/ext/spreadsheet/SpoutBuilder.php +++ b/src/ext/spreadsheet/SpoutBuilder.php @@ -22,10 +22,10 @@ class SpoutBuilder extends AbstractBuilder { const DATETIME_FORMAT = "mm/dd/yyyy hh:mm:ss"; /** @var bool faut-il choisir le type numérique pour une chaine numérique? */ - const PARSE_NUMERIC = true; + const TYPE_NUMERIC = true; /** @var bool faut-il choisir le type date pour une chaine au bon format? */ - const PARSE_DATE = true; + const TYPE_DATE = true; /** @var string|int|null nom de la feuille dans laquelle écrire */ const WSNAME = null; @@ -56,17 +56,17 @@ class SpoutBuilder extends AbstractBuilder { $ss->setDefaultColumnWidth(10.5); $ss->writeToStream($this->getResource()); $this->ss = $ss; - $this->parseNumeric = boolval($params["parse_numeric"] ?? static::PARSE_NUMERIC); - $this->parseDate = boolval($params["parse_date"] ?? static::PARSE_DATE); + $this->typeNumeric = boolval($params["type_numeric"] ?? static::TYPE_NUMERIC); + $this->typeDate = boolval($params["type_date"] ?? static::TYPE_DATE); $this->firstSheet = true; $this->setWsname($params["wsname"] ?? static::WSNAME); } protected WriterMultiSheetsAbstract $ss; - protected bool $parseNumeric; + protected bool $typeNumeric; - protected bool $parseDate; + protected bool $typeDate; const STYLE_ROW = 0, STYLE_HEADER = 1; @@ -94,7 +94,7 @@ class SpoutBuilder extends AbstractBuilder { } protected function isNumeric($value): bool { - if ($this->parseNumeric && is_numeric($value)) return true; + if ($this->typeNumeric && is_numeric($value)) return true; if (!is_string($value) && is_numeric($value)) return true; return false; } @@ -104,7 +104,7 @@ class SpoutBuilder extends AbstractBuilder { $style = (new Style())->setFormat(self::DATE_FORMAT); return true; } - if (!is_string($value)) return false; + if (!is_string($value) || !$this->typeDate) return false; if (DateTime::isa_datetime($value, true)) { $value = new DateTime($value); $style = (new Style())->setFormat(self::DATETIME_FORMAT); diff --git a/src/file/csv/AbstractReader.php b/src/file/csv/AbstractReader.php index 7ef5237..7c3db9f 100644 --- a/src/file/csv/AbstractReader.php +++ b/src/file/csv/AbstractReader.php @@ -12,13 +12,35 @@ abstract class AbstractReader implements IReader { /** @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->parseEmptyAsNull = boolval($params["empty_as_null"] ?? true); + $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; @@ -27,8 +49,14 @@ abstract class AbstractReader implements IReader { 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 { @@ -48,15 +76,32 @@ abstract class AbstractReader implements IReader { } protected function verifixCol(&$col): void { - if ($col === "" && $this->parseEmptyAsNull) { + if ($this->trim && is_string($col)) { + $col = trim($col); + } + if ($this->parseEmptyAsNull && $col === "") { # valeur vide --> null $col = null; - } elseif (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; + 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); + } } } }