["array", null, "liste et ordre des champs en sortie"], "output_headers" => ["bool", true, "faut-il afficher les en-têtes en sortie?"], ]; /** * @var array liste et ordre des champs en sortie. si cette valeur n'est pas * spécifiée, elle est calculée à partir du premier élément du flux. */ protected $ppHeaders; /** @var bool faut-il afficher les en-têtes en sortie? */ protected $ppOutputHeaders = true; private static final function is_different(array $h1, array $h2): bool { sort($h1); sort($h2); return $h1 != $h2; } private function computeHeaders(array $row) { return array_keys($row); } function _checkHeaders(?array $row): array { $skipLine = false; if ($row === null) { $outputHeaders = $this->ppOutputHeaders && $this->ppHeaders !== null; return [$skipLine, $outputHeaders, $this->ppHeaders]; } $prevHeaders = $this->ppHeaders; if ($this->ppMultiSchema) { # vérifier si le schéma a changé $headers = $this->computeHeaders($row); if ($prevHeaders === null) $prevHeaders = $headers; if (self::is_different($prevHeaders, $headers)) { $skipLine = true; $this->ppOutputHeaders = true; } else { $headers = $prevHeaders; } } else { $headers = $prevHeaders; if ($headers === null) $headers = $this->computeHeaders($row); } return [$skipLine, $this->ppOutputHeaders, $headers]; } function _setOutputHeaders(array $headers): void { $this->ppHeaders = $headers; $this->ppOutputHeaders = false; } function _cookHeaders(array $headers): array { return $headers; } function _cookValues(array $headers, array $row): array { $values = []; foreach ($headers as $header) { $values[] = A::get($row, $header, false); } return $values; } function getLine(array $values, bool $stripNl=true): string { $tmpf = fopen("php://memory", "w+b"); fputcsv($tmpf, $values, $this->separator, $this->enclosure, $this->escape); rewind($tmpf); $line = stream_get_contents($tmpf); if ($stripNl) $line = str::strip_nl($line); fclose($tmpf); return $line; } function mapper($item) { if ($this->eof) $row = null; else $row = A::with($item); $lines = []; [$skipLine, $outputHeaders, $headers] = $this->_checkHeaders($row); if ($skipLine) $lines[] = ""; if ($outputHeaders) { $lines[] = $this->getLine($this->_cookHeaders($headers)); $this->_setOutputHeaders($headers); } if ($row !== null) { $lines[] = $this->getLine($this->_cookValues($headers, $row)); } $this->mapTo($lines); } ############################################################################# const _AUTOGEN_CONSTS = [ "" => [self::class, "_autogen_consts"], ]; const _AUTOGEN_LITERALS = /*autogen*/[ [ \nur\b\params\parametrable_utils::class, '\\nur\\b\\params\\parametrable_utils::class', ], [ self::PARAMETRABLE_PARAMS_SCHEMA, 'self::PARAMETRABLE_PARAMS_SCHEMA', ], ]; const _AUTOGEN_METHODS = /*autogen*/[ [ \nur\b\params\parametrable_utils::class, '_autogen_methods_getters', self::PARAMETRABLE_PARAMS_SCHEMA, null, ], [ \nur\b\params\parametrable_utils::class, '_autogen_methods_setters', self::PARAMETRABLE_PARAMS_SCHEMA, null, ], ]; const _AUTO_GETTERS = /*autogen*/[ 'getHeaders' => 'headers', 'isOutputHeaders' => 'output_headers', ]; const _AUTO_SETTERS = /*autogen*/[ 'setHeaders' => 'headers', 'setOutputHeaders' => 'output_headers', ]; #--autogen-dynamic-- }