nur-sery/nur_src/mapper/item/SchemaMapper.php

261 lines
7.9 KiB
PHP
Raw Normal View History

2024-04-04 16:26:22 +04:00
<?php
namespace nur\mapper\item;
use nur\A;
use nur\b\IllegalAccessException;
use nur\b\params\Tparametrable;
use nur\b\ValueException;
use nur\data\types\Metadata;
use nur\mapper\base\Mapper;
/**
* Class SchemaMapper
*
* --autogen-properties-and-methods--
* @method bool isUseKey()
* @method bool isEnsureKnownTypes()
* @method bool isRecursive()
* @method bool isEnsureTypes()
* @method bool isThrow()
* @method bool isKeepResults()
* @method bool isCheckRequired()
* @method array|null setSchema(?array $value)
* @method bool setUseKey(bool $value)
* @method bool setEnsureKnownTypes(bool $value)
* @method bool setRecursive(bool $value)
* @method bool setEnsureTypes(bool $value)
* @method bool setThrow(bool $value)
* @method bool setKeepResults(bool $value)
* @method bool setCheckRequired(bool $value)
*/
class SchemaMapper extends Mapper {
use Tparametrable;
protected function SCHEMA(): ?array {
return self::SCHEMA;
} const SCHEMA = null;
function __construct(?array $schema=null, ?iterable $source=null) {
parent::__construct($source);
$this->pp_setSchema($schema);
}
const MULTIPLEX_RESULTS_COLS = "cols";
const MULTIPLEX_RESULTS_ROWS = "rows";
const PARAMETRABLE_PARAMS_SCHEMA = [
"schema" => ["?array", null, "schéma des données"],
"use_key" => ["bool", false, "faut-il tenir compte des clés fournies par la source"],
"ensure_known_types" => ["bool", false, "faut-il vérifier et convertir les types connus?"],
"recursive" => ["bool", true, "faut-il appliquer les schémas de façon récursive"],
"ensure_types" => ["bool", true, "faut-il vérifier et convertir les types connus?"],
"throw" => ["bool", false, "faut-il lancer une exception si certains champs sont invalides?"],
"keep_results" => ["bool", false, "faut-il garder le résultat des analyses et l'insérer dans le flux?"],
"multiplex_results" => [["string"], null, "faut-il multiplexer champs et résultats d'analyse",
"allowed_values" => [self::MULTIPLEX_RESULTS_COLS, self::MULTIPLEX_RESULTS_ROWS],
],
"check_required" => ["bool", false, "faut-il vérifier que les champs requis soient présents"],
];
/** @var Metadata */
protected $md;
function pp_setSchema(?array $schema): self {
if ($schema === null) $schema = $this->SCHEMA();
if ($schema !== null) $this->md = new Metadata($schema);
return $this;
}
/** @var bool */
protected $ppUseKey;
/** @var bool */
protected $ppEnsureKnownTypes;
/** @var bool */
protected $ppRecursive;
/** @var bool */
protected $ppEnsureTypes;
/** @var bool */
protected $ppThrow;
/** @var bool */
protected $ppKeepResults;
/** @var string|null */
protected $ppMultiplexResults;
function pp_setMultiplexResults(string $multiplexResults): self {
switch ($multiplexResults) {
case "cols":
case "col":
case "c":
$multiplexResults = self::MULTIPLEX_RESULTS_COLS;
break;
case "rows":
case "row":
case "r":
$multiplexResults = self::MULTIPLEX_RESULTS_ROWS;
break;
default:
throw ValueException::unexpected_value($multiplexResults, [
self::MULTIPLEX_RESULTS_COLS,
self::MULTIPLEX_RESULTS_ROWS,
]);
}
$this->ppMultiplexResults = $multiplexResults;
return $this;
}
function setMultiplexResults(string $multiplexResults=self::MULTIPLEX_RESULTS_COLS): void {
$this->pp_setMultiplexResults($multiplexResults);
}
/** @var bool */
protected $ppCheckRequired;
const OKEY_NB_ERRORS_TOTAL = "nb_errors_total";
function getNbErrorsTotal(): int {
return $this->getOvalue(self::OKEY_NB_ERRORS_TOTAL);
}
protected function setup(): void {
$this->setOvalue(self::OKEY_NB_ERRORS_TOTAL, 0);
}
function mapper($item, $key=null) {
if (!$this->ppUseKey) $key = null;
$md = $this->md;
$md->ensureSchema($item, $key, ["recursive" => $this->ppRecursive]);
$itemResults = null;
if ($this->ppEnsureTypes) {
$md->verifix($item, $results, $this->ppThrow, $this->ppRecursive);
$nbErrors = 0;
foreach ($results as $result) {
if (!$result["valid"]) {
$nbErrors++;
$this->incOvalue(self::OKEY_NB_ERRORS_TOTAL);
}
}
if ($this->ppKeepResults) {
$item = [
"item" => $item,
"results" => $results,
"nb_errors" => $nbErrors,
];
} elseif ($this->ppMultiplexResults !== null) {
switch ($this->ppMultiplexResults) {
case "cols":
$mitem = ["[nb_errors]" => $nbErrors];
foreach ($item as $key => $value) {
$mitem[$key] = $value;
$result = A::get($results, $key);
if ($result !== null) {
$result = $result["valid"]? null: $result["error"];
}
$mitem["[${key}_error]"] = $result;
}
foreach ($md->getCikeys() as $key) {
$result = A::get($results, $key);
if ($result !== null) {
$result = $result["valid"]? null: $result["error"];
}
$mitem["[${key}_error]"] = $result;
}
$item = $mitem;
break;
case "rows":
# construire la ligne avec les résultats
$mitem = ["[nb_errors]" => $nbErrors];
foreach ($item as $key => $value) {
$result = A::get($results, $key);
if ($result !== null) {
$result = $result["valid"]? null: $result["error"];
}
$mitem[$key] = $result;
}
foreach ($md->getCikeys() as $key) {
$result = A::get($results, $key);
if ($result !== null) {
$result = $result["valid"]? null: $result["error"];
}
$mitem[$key] = $result;
}
$itemResults = $mitem;
# puis ajouter la colonne manquante dans l'objet original
$mitem = ["[nb_errors]" => $nbErrors];
foreach ($item as $key => $value) {
$mitem[$key] = $value;
}
foreach ($md->getCikeys() as $key) {
$mitem[$key] = null;
}
$item = $mitem;
break;
default:
throw IllegalAccessException::unexpected_state();
}
}
} elseif ($this->ppCheckRequired) {
$md->checkRequired($item);
}
if ($itemResults === null) return $item;
else return $this->mapTo([$item, $itemResults]);
}
#############################################################################
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*/[
'getSchema' => 'schema',
'isUseKey' => 'use_key',
'isEnsureKnownTypes' => 'ensure_known_types',
'isRecursive' => 'recursive',
'isEnsureTypes' => 'ensure_types',
'isThrow' => 'throw',
'isKeepResults' => 'keep_results',
'getMultiplexResults' => 'multiplex_results',
'isCheckRequired' => 'check_required',
];
const _AUTO_SETTERS = /*autogen*/[
'setSchema' => 'schema',
'setUseKey' => 'use_key',
'setEnsureKnownTypes' => 'ensure_known_types',
'setRecursive' => 'recursive',
'setEnsureTypes' => 'ensure_types',
'setThrow' => 'throw',
'setKeepResults' => 'keep_results',
'setMultiplexResults' => 'multiplex_results',
'setCheckRequired' => 'check_required',
];
#--autogen-dynamic--
}