modifs.mineures sans commentaires
This commit is contained in:
		
							parent
							
								
									ea1b774d0f
								
							
						
					
					
						commit
						3028fe12f7
					
				
							
								
								
									
										1
									
								
								TODO.md
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO.md
									
									
									
									
									
								
							@ -2,7 +2,6 @@
 | 
			
		||||
 | 
			
		||||
## schema
 | 
			
		||||
 | 
			
		||||
* [ ] properties dans ScalarSchema, avec aliases pour notamment "nature" => ""
 | 
			
		||||
* [ ] remplacer IValue et TValue par une classe abstraite Value
 | 
			
		||||
 | 
			
		||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\values;
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class Result: résultat de l'analyse ou de la normalisation d'une valeur
 | 
			
		||||
@ -2,28 +2,29 @@
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
 | 
			
		||||
use ArrayAccess;
 | 
			
		||||
use BadMethodCallException;
 | 
			
		||||
use LogicException;
 | 
			
		||||
use nulib\cl;
 | 
			
		||||
use nur\sery\schema\values\IValue;
 | 
			
		||||
use nur\sery\schema\schemas\AssocSchema;
 | 
			
		||||
use nur\sery\schema\schemas\ListSchema;
 | 
			
		||||
use nur\sery\schema\schemas\ScalarSchema;
 | 
			
		||||
 | 
			
		||||
abstract class Schema implements ArrayAccess {
 | 
			
		||||
  /**
 | 
			
		||||
   * créer si besoin une nouvelle instance à partir d'une définition de schéma
 | 
			
		||||
   */
 | 
			
		||||
  static function new(&$md, $definition): self {
 | 
			
		||||
    if ($md === null) {
 | 
			
		||||
  static function ns(?Schema &$schema, $definition): self {
 | 
			
		||||
    if ($schema === null) {
 | 
			
		||||
      if (AssocSchema::isa_definition($definition)) {
 | 
			
		||||
        $md = new AssocSchema($definition);
 | 
			
		||||
        $schema = new AssocSchema($definition);
 | 
			
		||||
      } elseif (ListSchema::isa_definition($definition)) {
 | 
			
		||||
        $md = new ListSchema($definition);
 | 
			
		||||
        $schema = new ListSchema($definition);
 | 
			
		||||
      } elseif (ScalarSchema::isa_definition($definition)) {
 | 
			
		||||
        $md = new ScalarSchema($definition);
 | 
			
		||||
        $schema = new ScalarSchema($definition);
 | 
			
		||||
      } else {
 | 
			
		||||
        throw SchemaException::invalid_schema();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return $md;
 | 
			
		||||
    return $schema;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@ -42,8 +43,11 @@ abstract class Schema implements ArrayAccess {
 | 
			
		||||
  /** retourner true si le schéma est de nature scalaire */
 | 
			
		||||
  function isScalar(?ScalarSchema &$scalar=null): bool { return false; }
 | 
			
		||||
 | 
			
		||||
  abstract function getValue(&$value, $key=null): IValue;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Créer si besoin une nouvelle instance de {@link Value} qui référence la
 | 
			
		||||
   * variable $dest
 | 
			
		||||
   */
 | 
			
		||||
  abstract function nv(?Value &$value=null, &$dest=null, $key=null): Value;
 | 
			
		||||
 | 
			
		||||
  #############################################################################
 | 
			
		||||
  # key & properties
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								src/schema/Value.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/schema/Value.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
 | 
			
		||||
use nur\sery\schema\types\IType;
 | 
			
		||||
use nur\sery\schema\values\AssocValue;
 | 
			
		||||
use nur\sery\schema\values\ListValue;
 | 
			
		||||
use nur\sery\schema\values\ScalarValue;
 | 
			
		||||
 | 
			
		||||
abstract class Value {
 | 
			
		||||
  function isAssoc(?AssocValue &$assoc=null): bool { return false; }
 | 
			
		||||
  function isList(?ListValue &$list=null): bool { return false; }
 | 
			
		||||
  function isScalar(?ScalarValue &$scalar=null): bool { return false; }
 | 
			
		||||
 | 
			
		||||
  abstract function reset(&$dest, $key=null, bool $verifix=true): self;
 | 
			
		||||
 | 
			
		||||
  /** retourner le type associé à cette valeur */
 | 
			
		||||
  abstract function getType(): IType;
 | 
			
		||||
 | 
			
		||||
  /** retourner true si la valeur existe */
 | 
			
		||||
  abstract function exists(): bool;
 | 
			
		||||
 | 
			
		||||
  /** retourner true si la valeur est valide */
 | 
			
		||||
  abstract function valid(): bool;
 | 
			
		||||
 | 
			
		||||
  /** retourner true si la valeur est dans sa forme normalisée */
 | 
			
		||||
  abstract function normalized(): bool;
 | 
			
		||||
}
 | 
			
		||||
@ -1,32 +1,36 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\input;
 | 
			
		||||
 | 
			
		||||
#XXX available permet de préciser qu'une valeur doit exister et être non vide
 | 
			
		||||
# pour être considérée. en faire un paramètre, à moins que ce soit au niveau du
 | 
			
		||||
# type qu'il faille le gérer?
 | 
			
		||||
/**
 | 
			
		||||
 * Class Input: accès à une valeur
 | 
			
		||||
 *
 | 
			
		||||
 * cette implémentation lit depuis et écrit dans une référence
 | 
			
		||||
 */
 | 
			
		||||
class Input {
 | 
			
		||||
  function __construct(&$value=null) {
 | 
			
		||||
    $this->value =& $value;
 | 
			
		||||
  function __construct(&$dest=null) {
 | 
			
		||||
    $this->dest =& $dest;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected $value;
 | 
			
		||||
  protected $dest;
 | 
			
		||||
 | 
			
		||||
  /** tester si la valeur existe */
 | 
			
		||||
  function exists($key=null): bool {
 | 
			
		||||
    if ($key === null) return true;
 | 
			
		||||
    return $this->value !== null && array_key_exists($key, $this->value);
 | 
			
		||||
    return $this->dest !== null && array_key_exists($key, $this->dest);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function get($key=null) {
 | 
			
		||||
    if ($key === null) return $this->value;
 | 
			
		||||
    elseif ($this->value === null) return null;
 | 
			
		||||
    elseif (!array_key_exists($key, $this->value)) return null;
 | 
			
		||||
    else return $this->value[$key];
 | 
			
		||||
    if ($key === null) return $this->dest;
 | 
			
		||||
    elseif ($this->dest === null) return null;
 | 
			
		||||
    elseif (!array_key_exists($key, $this->dest)) return null;
 | 
			
		||||
    else return $this->dest[$key];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function set($value, $key=null): void {
 | 
			
		||||
    if ($key === null) $this->value = $value;
 | 
			
		||||
    else $this->value[$key] = $value;
 | 
			
		||||
    if ($key === null) $this->dest = $value;
 | 
			
		||||
    else $this->dest[$key] = $value;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,12 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
namespace nur\sery\schema\schemas;
 | 
			
		||||
 | 
			
		||||
use nulib\cl;
 | 
			
		||||
use nur\sery\schema\input\Input;
 | 
			
		||||
use nur\sery\schema\Schema;
 | 
			
		||||
use nur\sery\schema\Value;
 | 
			
		||||
use nur\sery\schema\values\AssocValue;
 | 
			
		||||
use nur\sery\schema\values\ScalarValue;
 | 
			
		||||
 | 
			
		||||
class AssocSchema extends Schema {
 | 
			
		||||
  /** @var array meta-schema d'un schéma de nature tableau associatif */
 | 
			
		||||
@ -29,7 +34,6 @@ class AssocSchema extends Schema {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static function normalize($definition): array {
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function __construct($definition=null, bool $normalize=true) {
 | 
			
		||||
@ -42,4 +46,11 @@ class AssocSchema extends Schema {
 | 
			
		||||
    $assoc = $this;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function nv(?Value &$value=null, &$dest=null, $key=null): Value {
 | 
			
		||||
    if (!($value instanceof AssocValue)) $value = new AssocValue($this);
 | 
			
		||||
    if ($dest instanceof Input) $input = $dest;
 | 
			
		||||
    else $input = new Input($dest);
 | 
			
		||||
    return $value->reset($input, $key);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,10 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
namespace nur\sery\schema\schemas;
 | 
			
		||||
 | 
			
		||||
use nur\sery\schema\input\Input;
 | 
			
		||||
use nur\sery\schema\Schema;
 | 
			
		||||
use nur\sery\schema\Value;
 | 
			
		||||
use nur\sery\schema\values\ListValue;
 | 
			
		||||
 | 
			
		||||
class ListSchema extends Schema {
 | 
			
		||||
  /** @var array meta-schema d'un schéma de nature liste */
 | 
			
		||||
@ -29,7 +34,6 @@ class ListSchema extends Schema {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static function normalize($definition): array {
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function __construct($definition=null, bool $normalize=true) {
 | 
			
		||||
@ -42,4 +46,11 @@ class ListSchema extends Schema {
 | 
			
		||||
    $list = $this;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function nv(?Value &$value=null, &$dest=null, $key=null): Value {
 | 
			
		||||
    if (!($value instanceof ListValue)) $value = new ListValue($this);
 | 
			
		||||
    if ($dest instanceof Input) $input = $dest;
 | 
			
		||||
    else $input = new Input($dest);
 | 
			
		||||
    return $value->reset($input, $key);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,17 +1,19 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
namespace nur\sery\schema\schemas;
 | 
			
		||||
 | 
			
		||||
use nulib\cl;
 | 
			
		||||
use nur\sery\schema\input\Input;
 | 
			
		||||
use nur\sery\schema\ref\ref_schema;
 | 
			
		||||
use nur\sery\schema\ref\ref_types;
 | 
			
		||||
use nur\sery\schema\Schema;
 | 
			
		||||
use nur\sery\schema\SchemaException;
 | 
			
		||||
use nur\sery\schema\types\tarray;
 | 
			
		||||
use nur\sery\schema\types\tbool;
 | 
			
		||||
use nur\sery\schema\types\tcallable;
 | 
			
		||||
use nur\sery\schema\types\tcontent;
 | 
			
		||||
use nur\sery\schema\types\tpkey;
 | 
			
		||||
use nur\sery\schema\types\tstring;
 | 
			
		||||
use nur\sery\schema\values\IValue;
 | 
			
		||||
use nur\sery\schema\Value;
 | 
			
		||||
use nur\sery\schema\values\ScalarValue;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -180,10 +182,9 @@ class ScalarSchema extends Schema {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getValue(&$value, $key=null): IValue {
 | 
			
		||||
    if ($value instanceof Input) $input = $value;
 | 
			
		||||
    else $input = new Input($value);
 | 
			
		||||
    return new ScalarValue($input, $this, $key);
 | 
			
		||||
  function nv(?Value &$value=null, &$dest=null, $key=null): Value {
 | 
			
		||||
    if (!($value instanceof ScalarValue)) $value = new ScalarValue($this);
 | 
			
		||||
    return $value->reset($dest, $key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #############################################################################
 | 
			
		||||
							
								
								
									
										37
									
								
								src/schema/types.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/schema/types.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
 | 
			
		||||
use nur\sery\schema\types\IType;
 | 
			
		||||
use nur\sery\schema\types\Registry;
 | 
			
		||||
use nur\sery\schema\types\tarray;
 | 
			
		||||
use nur\sery\schema\types\tbool;
 | 
			
		||||
use nur\sery\schema\types\tcallable;
 | 
			
		||||
use nur\sery\schema\types\tfloat;
 | 
			
		||||
use nur\sery\schema\types\tint;
 | 
			
		||||
use nur\sery\schema\types\tstring;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class types: classe outil pour gérer le registre de types
 | 
			
		||||
 */
 | 
			
		||||
class types {
 | 
			
		||||
  /** @var Registry */
 | 
			
		||||
  private static $registry;
 | 
			
		||||
 | 
			
		||||
  static function registry(): Registry {
 | 
			
		||||
    if (self::$registry === null) {
 | 
			
		||||
      self::$registry = new Registry();
 | 
			
		||||
    }
 | 
			
		||||
    return self::$registry;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static function get(string $name): IType {
 | 
			
		||||
    return self::registry()->get($name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static function string(): tstring { return self::get("string"); }
 | 
			
		||||
  static function bool(): tbool { return self::get("bool"); }
 | 
			
		||||
  static function int(): tint { return self::get("int"); }
 | 
			
		||||
  static function float(): tfloat { return self::get("float"); }
 | 
			
		||||
  static function array(): tarray { return self::get("array"); }
 | 
			
		||||
  static function callable(): tcallable { return self::get("callable"); }
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
use nur\sery\schema\values\Result;
 | 
			
		||||
use nur\sery\schema\Result;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface IType: un type de données
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								src/schema/types/Registry.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/schema/types/Registry.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class Registry {
 | 
			
		||||
  const TYPES = [
 | 
			
		||||
    "string" => tstring::class,
 | 
			
		||||
    "bool" => tbool::class, "boolean" => tbool::class,
 | 
			
		||||
    "int" => tint::class, "integer" => tint::class,
 | 
			
		||||
    "float" => tfloat::class, "flt" => tfloat::class,
 | 
			
		||||
    "double" => tfloat::class, "dbl" => tfloat::class,
 | 
			
		||||
    "array" => tarray::class,
 | 
			
		||||
    "callable" => tcallable::class,
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  function __construct() {
 | 
			
		||||
    $this->types = [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** @var IType[] */
 | 
			
		||||
  protected $types;
 | 
			
		||||
 | 
			
		||||
  function get(string $name): IType {
 | 
			
		||||
    #XXX les instancier
 | 
			
		||||
    return $this->types[$name];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -3,7 +3,7 @@ namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
use nulib\cl;
 | 
			
		||||
 | 
			
		||||
class tarray {
 | 
			
		||||
class tarray implements IType {
 | 
			
		||||
  static function ensure_array(&$array): void {
 | 
			
		||||
    if (!is_array($array)) $array = cl::with($array);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class tbool {
 | 
			
		||||
class tbool implements IType {
 | 
			
		||||
  static function ensure_bool(&$bool): void {
 | 
			
		||||
    if (!is_bool($bool)) $bool = boolval($bool);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
use nur\sery\schema\SchemaException;
 | 
			
		||||
 | 
			
		||||
class tcallable {
 | 
			
		||||
class tcallable implements IType {
 | 
			
		||||
  static function ensure_callable(&$callable): void {
 | 
			
		||||
    if (!is_callable($callable)) throw SchemaException::invalid_callable($callable);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class tcontent {
 | 
			
		||||
class tcontent implements IType {
 | 
			
		||||
  static function ensure_content(&$content): void {
 | 
			
		||||
    if (!is_string($content) && !is_array($content)) $content = strval($content);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								src/schema/types/tfloat.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/schema/types/tfloat.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class tfloat implements IType {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								src/schema/types/tint.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/schema/types/tint.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class tint implements IType {
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class tkey {
 | 
			
		||||
class tkey implements IType {
 | 
			
		||||
  static function ensure_key(&$key): void {
 | 
			
		||||
    if (!is_string($key) && !is_int($key)) $key = strval($key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class tpkey {
 | 
			
		||||
class tpkey implements IType {
 | 
			
		||||
  static function ensure_pkey(&$pkey): void {
 | 
			
		||||
    if (!is_string($pkey) && !is_int($pkey) && !is_array($pkey)) $pkey = strval($pkey);
 | 
			
		||||
    if (is_array($pkey)) {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\types;
 | 
			
		||||
 | 
			
		||||
class tstring {
 | 
			
		||||
class tstring implements IType {
 | 
			
		||||
  static function ensure_string(&$string): void {
 | 
			
		||||
    if (!is_string($string)) $string = strval($string);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,10 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\values;
 | 
			
		||||
 | 
			
		||||
class AssocValue implements IValue {
 | 
			
		||||
  use TValue;
 | 
			
		||||
use nur\sery\schema\Value;
 | 
			
		||||
use nur\sery\schema\Result;
 | 
			
		||||
 | 
			
		||||
  function isScalar(?ScalarValue &$scalar=null): bool { return false; }
 | 
			
		||||
  function isList(?ListValue &$list=null): bool { return false; }
 | 
			
		||||
class AssocValue extends Value {
 | 
			
		||||
  function isAssoc(?AssocValue &$assoc=null): bool { $assoc = $this; return true; }
 | 
			
		||||
 | 
			
		||||
  function ensureKeys(): bool {
 | 
			
		||||
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\values;
 | 
			
		||||
 | 
			
		||||
use nur\sery\schema\types\IType;
 | 
			
		||||
 | 
			
		||||
interface IValue {
 | 
			
		||||
  /** retourner true si cette valeur est scalaire */
 | 
			
		||||
  function isScalar(?ScalarValue &$scalar=null): bool;
 | 
			
		||||
 | 
			
		||||
  /** retourner true cette valeur est une liste */
 | 
			
		||||
  function isList(?ListValue &$list=null): bool;
 | 
			
		||||
 | 
			
		||||
  /** retourner true cette valeur est un tableau associatif */
 | 
			
		||||
  function isAssoc(?AssocValue &$assoc=null): bool;
 | 
			
		||||
 | 
			
		||||
  function reset(&$value, $key=null, bool $verifix=true): void;
 | 
			
		||||
 | 
			
		||||
  /** retourner true si la valeur existe */
 | 
			
		||||
  function exists(): bool;
 | 
			
		||||
 | 
			
		||||
  /** retourner true si la valeur est valide */
 | 
			
		||||
  function isValid(): bool;
 | 
			
		||||
 | 
			
		||||
  /** retourner true si la valeur est dans sa forme normalisée */
 | 
			
		||||
  function isNormalized();
 | 
			
		||||
 | 
			
		||||
  /** retourner le type associé à cette valeur */
 | 
			
		||||
  function getType(): IType;
 | 
			
		||||
}
 | 
			
		||||
@ -1,12 +1,11 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\values;
 | 
			
		||||
 | 
			
		||||
class ListValue implements IValue {
 | 
			
		||||
  use TValue;
 | 
			
		||||
use nur\sery\schema\Result;
 | 
			
		||||
use nur\sery\schema\Value;
 | 
			
		||||
 | 
			
		||||
  function isScalar(?ScalarValue &$scalar=null): bool { return false; }
 | 
			
		||||
class ListValue extends Value {
 | 
			
		||||
  function isList(?ListValue &$list=null): bool { $list = $this; return true; }
 | 
			
		||||
  function isAssoc(?AssocValue &$assoc=null): bool { return false; }
 | 
			
		||||
 | 
			
		||||
  function ensureKeys(): bool {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,52 +1,71 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\values;
 | 
			
		||||
 | 
			
		||||
use nur\sery\schema\ScalarSchema;
 | 
			
		||||
use nur\sery\schema\input\Input;
 | 
			
		||||
use nur\sery\schema\Result;
 | 
			
		||||
use nur\sery\schema\schemas\ScalarSchema;
 | 
			
		||||
use nur\sery\schema\types\IType;
 | 
			
		||||
use nur\sery\schema\Value;
 | 
			
		||||
 | 
			
		||||
class ScalarValue implements IValue {
 | 
			
		||||
  use TValue;
 | 
			
		||||
class ScalarValue extends Value {
 | 
			
		||||
  function __construct(ScalarSchema $schema, &$dest=null, $key=null, bool $verifix=true) {
 | 
			
		||||
    $this->schema = $schema;
 | 
			
		||||
    $this->reset($dest, $key, $verifix);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; }
 | 
			
		||||
 | 
			
		||||
  /** @var ScalarSchema schéma de cette valeur */
 | 
			
		||||
  protected $schema;
 | 
			
		||||
 | 
			
		||||
  /** @var Input source et destination de la valeur */
 | 
			
		||||
  protected $input;
 | 
			
		||||
 | 
			
		||||
  /** @var string|int clé de la valeur dans le tableau destination */
 | 
			
		||||
  protected $key;
 | 
			
		||||
 | 
			
		||||
  /** @var ?Result résultat de l'analyse de la valeur */
 | 
			
		||||
  protected $result;
 | 
			
		||||
 | 
			
		||||
  function __construct(&$value, ScalarSchema $schema, $key=null, bool $verifix=true) {
 | 
			
		||||
    $this->schema = $schema;
 | 
			
		||||
    $this->reset($value, $key, $verifix);
 | 
			
		||||
    #XXX résoudre les type dans reset()?
 | 
			
		||||
  function reset(&$dest, $key=null, bool $verifix=true): Value {
 | 
			
		||||
    if ($dest instanceof Input) $input = $dest;
 | 
			
		||||
    else $input = new Input($dest);
 | 
			
		||||
    $this->input = $input;
 | 
			
		||||
    $this->key = $key;
 | 
			
		||||
    $this->result = null;
 | 
			
		||||
    #XXX résoudre les types ici?
 | 
			
		||||
    if ($verifix) $this->verifix();
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; }
 | 
			
		||||
  function isList(?ListValue &$list=null): bool { return false; }
 | 
			
		||||
  function isAssoc(?AssocValue &$assoc=null): bool { return false; }
 | 
			
		||||
  function exists(): bool {
 | 
			
		||||
    return $this->input->exists($this->key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function get($default=null) {
 | 
			
		||||
    $key = $this->key;
 | 
			
		||||
    if ($key === null) return $this->value;
 | 
			
		||||
    elseif (array_key_exists($key, $this->value)) return $this->value[$key];
 | 
			
		||||
    $input = $this->input;
 | 
			
		||||
    if ($input->exists($key)) return $input->get($key);
 | 
			
		||||
    else return $default;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function set($value): self {
 | 
			
		||||
    $key = $this->key;
 | 
			
		||||
    if ($key === null) $this->value = $value;
 | 
			
		||||
    else $this->value[$key] = $value;
 | 
			
		||||
    $this->input->set($value, $this->key);
 | 
			
		||||
    return $this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** @var IType */
 | 
			
		||||
  protected $type;
 | 
			
		||||
 | 
			
		||||
  function type(): IType {
 | 
			
		||||
  function getType(): IType {
 | 
			
		||||
    if ($this->type === null) $this->type = $this->schema->getType($this->key);
 | 
			
		||||
    return $this->type;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function exists(): bool {
 | 
			
		||||
    return $this->type()->exists($this->value, $this->key);
 | 
			
		||||
  function valid(): bool {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function normalized(): bool {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@ -55,25 +74,25 @@ class ScalarValue implements IValue {
 | 
			
		||||
   * si la valeur était déjà normalisée, retourner false.
 | 
			
		||||
   */
 | 
			
		||||
  function verifix(bool $throw=true, ?Result &$result=null): bool {
 | 
			
		||||
    $type = $this->type();
 | 
			
		||||
    $type = $this->getType();
 | 
			
		||||
    $key = $this->key;
 | 
			
		||||
    if ($key === null) $modified = $type->verifix($this->value, $throw, $result);
 | 
			
		||||
    else $modified = $type->verifix($this->value[$key], $throw, $result);
 | 
			
		||||
    if ($key === null) $modified = $type->verifix($this->input, $throw, $result);
 | 
			
		||||
    else $modified = $type->verifix($this->input[$key], $throw, $result);
 | 
			
		||||
    $this->result = $result;
 | 
			
		||||
    return $modified;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function parse($value, bool $throw=true, ?Result &$result=null) {
 | 
			
		||||
    $this->type()->verifix($value, $throw, $result);
 | 
			
		||||
    $this->getType()->verifix($value, $throw, $result);
 | 
			
		||||
    $this->set($value);
 | 
			
		||||
    $this->result = $result;
 | 
			
		||||
    return $value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function format(?string $format=null): string {
 | 
			
		||||
    $type = $this->type();
 | 
			
		||||
    $type = $this->getType();
 | 
			
		||||
    $key = $this->key;
 | 
			
		||||
    if ($key === null) return $type->format($this->value, $format);
 | 
			
		||||
    else return $type->format($this->value[$key], $format);
 | 
			
		||||
    if ($key === null) return $type->format($this->input, $format);
 | 
			
		||||
    else return $type->format($this->input[$key], $format);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema\values;
 | 
			
		||||
 | 
			
		||||
trait TValue {
 | 
			
		||||
  /** @var mixed valeur ou référence d'un tableau contenant la valeur */
 | 
			
		||||
  protected $value;
 | 
			
		||||
 | 
			
		||||
  /** @var string|int clé de la valeur dans le tableau destination */
 | 
			
		||||
  protected $key;
 | 
			
		||||
 | 
			
		||||
  function reset(&$value, $key=null, bool $verifix=true): void {
 | 
			
		||||
    $this->value =& $value;
 | 
			
		||||
    $this->key = $key;
 | 
			
		||||
    $this->result = null;
 | 
			
		||||
    if ($verifix) $this->verifix();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								tests/schema/schemaTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								tests/schema/schemaTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,106 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
 | 
			
		||||
use Exception;
 | 
			
		||||
use nulib\tests\TestCase;
 | 
			
		||||
use nur\sery\schema\values\ScalarValue;
 | 
			
		||||
 | 
			
		||||
class schemaTest extends TestCase {
 | 
			
		||||
  function testInt() {
 | 
			
		||||
    Schema::ns($schema, "int");
 | 
			
		||||
    /** @var ScalarValue $intv */
 | 
			
		||||
    $schema->nv($intv, $int);
 | 
			
		||||
    $f = function($value) use($intv) {
 | 
			
		||||
      return function() use($intv, $value) {
 | 
			
		||||
        $intv->set($value);
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    self::assertException(Exception::class, $f(null));
 | 
			
		||||
    self::assertException(Exception::class, $f(""));
 | 
			
		||||
    self::assertException(Exception::class, $f(" "));
 | 
			
		||||
 | 
			
		||||
    $intv->set(12);
 | 
			
		||||
    self::assertSame(12, $intv->get());
 | 
			
		||||
    self::assertSame(12, $int);
 | 
			
		||||
    self::assertSame("12", $intv->format());
 | 
			
		||||
    self::assertSame("0012", $intv->format("%4u"));
 | 
			
		||||
 | 
			
		||||
    $intv->set("12");
 | 
			
		||||
    self::assertSame(12, $intv->get());
 | 
			
		||||
 | 
			
		||||
    $intv->set(" 12 ");
 | 
			
		||||
    self::assertSame(12, $intv->get());
 | 
			
		||||
 | 
			
		||||
    self::assertException(Exception::class, $f(true));
 | 
			
		||||
    self::assertException(Exception::class, $f(false));
 | 
			
		||||
    self::assertException(Exception::class, $f("a"));
 | 
			
		||||
    self::assertException(Exception::class, $f([]));
 | 
			
		||||
    self::assertException(Exception::class, $f(["a"]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function testNint() {
 | 
			
		||||
    Schema::ns($schema, ["?int"]);
 | 
			
		||||
    /** @var ScalarValue $intv */
 | 
			
		||||
    $schema->nv($intv, $int);
 | 
			
		||||
    $f = function($value) use($intv) {
 | 
			
		||||
      return function() use($intv, $value) {
 | 
			
		||||
        $intv->set($value);
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    $intv->set(null);
 | 
			
		||||
    self::assertNull($intv->get());
 | 
			
		||||
    self::assertNull($int);
 | 
			
		||||
    self::assertSame("", $intv->format());
 | 
			
		||||
 | 
			
		||||
    $intv->set("");
 | 
			
		||||
    self::assertNull($intv->get());
 | 
			
		||||
    self::assertNull($int);
 | 
			
		||||
    self::assertSame("", $intv->format());
 | 
			
		||||
 | 
			
		||||
    $intv->set(" ");
 | 
			
		||||
    self::assertNull($intv->get());
 | 
			
		||||
    self::assertNull($int);
 | 
			
		||||
    self::assertSame("", $intv->format());
 | 
			
		||||
 | 
			
		||||
    $intv->set(12);
 | 
			
		||||
    self::assertSame(12, $intv->get());
 | 
			
		||||
    self::assertSame(12, $int);
 | 
			
		||||
    self::assertSame("12", $intv->format());
 | 
			
		||||
    self::assertSame("0012", $intv->format("%4u"));
 | 
			
		||||
 | 
			
		||||
    $intv->set("12");
 | 
			
		||||
    self::assertSame(12, $int);
 | 
			
		||||
 | 
			
		||||
    $intv->set(" 12 ");
 | 
			
		||||
    self::assertSame(12, $int);
 | 
			
		||||
 | 
			
		||||
    self::assertException(Exception::class, $f(true));
 | 
			
		||||
    self::assertException(Exception::class, $f(false));
 | 
			
		||||
    self::assertException(Exception::class, $f("a"));
 | 
			
		||||
    self::assertException(Exception::class, $f([]));
 | 
			
		||||
    self::assertException(Exception::class, $f(["a"]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function testUnionTypes() {
 | 
			
		||||
    # l'ordre des types est respecté
 | 
			
		||||
    Schema::ns($schema, ["string|int"]);
 | 
			
		||||
    /** @var ScalarValue $siv */
 | 
			
		||||
    $schema->nv($siv, $si);
 | 
			
		||||
 | 
			
		||||
    $siv->set("12");
 | 
			
		||||
    self::assertSame("12", $si);
 | 
			
		||||
    $siv->set(12);
 | 
			
		||||
    self::assertSame(12, $si);
 | 
			
		||||
 | 
			
		||||
    Schema::ns($schema, ["int|string"]);
 | 
			
		||||
    /** @var ScalarValue $siv */
 | 
			
		||||
    $schema->nv($siv, $si);
 | 
			
		||||
 | 
			
		||||
    $siv->set("12");
 | 
			
		||||
    self::assertSame(12, $si);
 | 
			
		||||
    $siv->set(12);
 | 
			
		||||
    self::assertSame(12, $si);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,9 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\schema;
 | 
			
		||||
namespace nur\sery\schema\schemas;
 | 
			
		||||
 | 
			
		||||
use nulib\tests\TestCase;
 | 
			
		||||
use nur\sery\schema\SchemaException;
 | 
			
		||||
use nur\sery\schema\schemas\ScalarSchema;
 | 
			
		||||
 | 
			
		||||
class ScalarSchemaTest extends TestCase {
 | 
			
		||||
  const NULL_SCHEMA = [
 | 
			
		||||
@ -20,7 +22,7 @@ class ScalarSchemaTest extends TestCase {
 | 
			
		||||
    "format" => null,
 | 
			
		||||
    "" => ["scalar"],
 | 
			
		||||
    "name" => null,
 | 
			
		||||
    "key" => null,
 | 
			
		||||
    "pkey" => null,
 | 
			
		||||
    "header" => null,
 | 
			
		||||
    "composite" => null,
 | 
			
		||||
  ];
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user