261 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			261 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?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--
 | |
| }
 |