This commit is contained in:
Jephté Clain 2024-10-04 14:18:31 +04:00
commit c88277a6d6
5 changed files with 33 additions and 26 deletions

View File

@ -16,6 +16,12 @@ abstract class AbstractBuilder extends TempStream implements IBuilder {
/** @var ?array liste des colonnes à écrire */ /** @var ?array liste des colonnes à écrire */
const HEADERS = null; const HEADERS = null;
/**
* @var bool faut-il écrire les en-têtes, soit celles qui sont spécifiées,
* soit celles qui sont calculées à partir des clés de la première ligne
*/
const USE_HEADERS = true;
/** @var ?string nom du fichier téléchargé */ /** @var ?string nom du fichier téléchargé */
const OUTPUT = null; const OUTPUT = null;
@ -23,6 +29,7 @@ abstract class AbstractBuilder extends TempStream implements IBuilder {
if ($output !== null) $params["output"] = $output; if ($output !== null) $params["output"] = $output;
$this->schema = $params["schema"] ?? static::SCHEMA; $this->schema = $params["schema"] ?? static::SCHEMA;
$this->headers = $params["headers"] ?? static::HEADERS; $this->headers = $params["headers"] ?? static::HEADERS;
$this->useHeaders = $params["use_headers"] ?? static::USE_HEADERS;
$rows = $params["rows"] ?? null; $rows = $params["rows"] ?? null;
if (is_callable($rows)) $rows = $rows(); if (is_callable($rows)) $rows = $rows();
$this->rows = $rows; $this->rows = $rows;
@ -44,6 +51,8 @@ abstract class AbstractBuilder extends TempStream implements IBuilder {
protected ?array $headers; protected ?array $headers;
protected bool $useHeaders;
protected ?iterable $rows; protected ?iterable $rows;
protected ?string $output; protected ?string $output;
@ -53,7 +62,7 @@ abstract class AbstractBuilder extends TempStream implements IBuilder {
protected ?array $cookArgs; protected ?array $cookArgs;
protected function ensureHeaders(?array $row=null): void { protected function ensureHeaders(?array $row=null): void {
if ($this->headers !== null) return; if ($this->headers !== null || !$this->useHeaders) return;
if ($this->schema === null) $headers = null; if ($this->schema === null) $headers = null;
else $headers = array_keys($this->schema); else $headers = array_keys($this->schema);
if ($headers === null && $row !== null) $headers = array_keys($row); if ($headers === null && $row !== null) $headers = array_keys($row);
@ -66,9 +75,11 @@ abstract class AbstractBuilder extends TempStream implements IBuilder {
function writeHeaders(?array $headers=null): void { function writeHeaders(?array $headers=null): void {
if ($this->wroteHeaders) return; if ($this->wroteHeaders) return;
if ($this->useHeaders) {
if ($headers !== null) $this->headers = $headers; if ($headers !== null) $this->headers = $headers;
else $this->ensureHeaders(); else $this->ensureHeaders();
if ($this->headers !== null) $this->_write($this->headers); if ($this->headers !== null) $this->_write($this->headers);
}
$this->wroteHeaders = true; $this->wroteHeaders = true;
} }

View File

@ -11,7 +11,7 @@ abstract class AbstractReader implements IReader {
const HEADERS = null; const HEADERS = null;
/** @var bool faut-il utiliser les en-têtes pour retourner des tableaux associatifs? */ /** @var bool faut-il utiliser les en-têtes pour retourner des tableaux associatifs? */
const COOk_ROWS = true; const USE_HEADERS = true;
/** @var ?string nom du fichier depuis lequel lire */ /** @var ?string nom du fichier depuis lequel lire */
const INPUT = null; const INPUT = null;
@ -40,7 +40,7 @@ abstract class AbstractReader implements IReader {
# #
$this->schema = $params["schema"] ?? static::SCHEMA; $this->schema = $params["schema"] ?? static::SCHEMA;
$this->headers = $params["headers"] ?? static::HEADERS; $this->headers = $params["headers"] ?? static::HEADERS;
$this->cookRows = $params["cook_rows"] ?? static::COOk_ROWS; $this->useHeaders = $params["use_headers"] ?? static::USE_HEADERS;
$this->input = $params["input"] ?? static::INPUT; $this->input = $params["input"] ?? static::INPUT;
$this->trim = boolval($params["trim"] ?? static::TRIM); $this->trim = boolval($params["trim"] ?? static::TRIM);
$this->parseEmptyAsNull = boolval($params["empty_as_null"] ?? static::PARSE_EMPTY_AS_NULL); $this->parseEmptyAsNull = boolval($params["empty_as_null"] ?? static::PARSE_EMPTY_AS_NULL);
@ -52,7 +52,7 @@ abstract class AbstractReader implements IReader {
protected ?array $headers; protected ?array $headers;
protected bool $cookRows; protected bool $useHeaders;
protected $input; protected $input;
@ -67,7 +67,7 @@ abstract class AbstractReader implements IReader {
protected int $isrc = 0, $idest = 0; protected int $isrc = 0, $idest = 0;
protected function cookRow(array &$row): bool { protected function cookRow(array &$row): bool {
if (!$this->cookRows) return true; if (!$this->useHeaders) return true;
if ($this->isrc == 0) { if ($this->isrc == 0) {
# ligne d'en-tête # ligne d'en-tête
$headers = $this->headers; $headers = $this->headers;

View File

@ -1,7 +1,7 @@
<?php <?php
namespace nur\sery\file\csv; namespace nur\sery\file\csv;
interface IBuilder { interface IBuilder extends \nur\sery\file\IReader {
function writeHeaders(?array $headers=null): void; function writeHeaders(?array $headers=null): void;
function write(?array $row): void; function write(?array $row): void;

View File

@ -37,17 +37,15 @@ trait TAbstractBuilder {
$output = $params["output"] ?? null; $output = $params["output"] ?? null;
$ssType = null; $ssType = null;
if (is_string($output)) { if (is_string($output)) {
switch (path::ext($output)) { $ext = path::ext($output);
case ".csv": if ($output === "-" || $ext === ".csv") {
$class = CsvBuilder::class; $class = CsvBuilder::class;
break; } elseif ($ext === ".ods") {
case ".ods":
$ssType = "ods"; $ssType = "ods";
break; } elseif ($ext === ".xlsx") {
case ".xlsx": $ssType = "xlsx";
default: } else {
$ssType = "xlsx"; $ssType = "xlsx";
break;
} }
} }
$params["ss_type"] = $ssType; $params["ss_type"] = $ssType;

View File

@ -36,17 +36,15 @@ trait TAbstractReader {
$input = $params["input"] ?? null; $input = $params["input"] ?? null;
$ssType = null; $ssType = null;
if (is_string($input)) { if (is_string($input)) {
switch (path::ext($input)) { $ext = path::ext($input);
case ".csv": if ($input === "-" || $ext === ".csv") {
$class = CsvReader::class; $class = CsvReader::class;
break; } elseif ($ext === ".ods") {
case ".ods":
$ssType = "ods"; $ssType = "ods";
break; } elseif ($ext === ".xlsx") {
case ".xlsx": $ssType = "xlsx";
default: } else {
$ssType = "xlsx"; $ssType = "xlsx";
break;
} }
} }
$params["ss_type"] = $ssType; $params["ss_type"] = $ssType;