Compare commits
	
		
			52 Commits
		
	
	
		
			ee0234f6ba
			...
			e4860b1b39
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e4860b1b39 | |||
| 177e504ca8 | |||
| 9c659866ef | |||
| 555d15b9e4 | |||
| 2d73f4d234 | |||
| 3b13ef126c | |||
| 3933fd1e72 | |||
| 84bad2be0c | |||
| 587df17273 | |||
| 80fab7e636 | |||
| 4d238cc44e | |||
| e592e8b9c4 | |||
| 4353f482a4 | |||
| c71cc032fb | |||
| a045296629 | |||
| 68f5dc5209 | |||
| f005692cd8 | |||
| d844bd03ad | |||
| c4e02d5bcf | |||
| 2a92a9a07e | |||
| c274adb6e6 | |||
| ff02ffdf4f | |||
| 9109e0fe39 | |||
| fd1ebaf611 | |||
| 26817d2826 | |||
| 7257654753 | |||
| e2bec38540 | |||
| c2ec23be30 | |||
| 741a807420 | |||
| e9f4826a94 | |||
| fd9b3b29bc | |||
| f37a53cfbd | |||
| 6e8245dbcb | |||
| f4e252a6e0 | |||
| 19f6f9c9e1 | |||
| baa770d969 | |||
| c5bfa3940c | |||
| 39af99ffa4 | |||
| 1fc4e7637b | |||
| ef7e8551aa | |||
| 9328aac9e9 | |||
| 62fc315b9e | |||
| b9e91bd917 | |||
| 3608b02749 | |||
| d148850c12 | |||
| 189c7aba68 | |||
| 91e6c0dcd2 | |||
| bb311708d7 | |||
| 1feffb6c0f | |||
| 62987d576e | |||
| 5decd631e2 | |||
| c98afaa98c | 
@ -11,6 +11,6 @@ composer:
 | 
				
			|||||||
  dist:
 | 
					  dist:
 | 
				
			||||||
    link: false
 | 
					    link: false
 | 
				
			||||||
    require-dev:
 | 
					    require-dev:
 | 
				
			||||||
      nulib/php: ^0.4.0p74
 | 
					      nulib/php: ^0.5.0p74
 | 
				
			||||||
      nulib/spout: ^0.4.0p74
 | 
					      nulib/spout: ^0.5.0p74
 | 
				
			||||||
      nulib/phpss: ^0.4.0p74
 | 
					      nulib/phpss: ^0.5.0p74
 | 
				
			||||||
							
								
								
									
										6
									
								
								.idea/nur-ture.iml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								.idea/nur-ture.iml
									
									
									
										generated
									
									
									
								
							@ -4,10 +4,8 @@
 | 
				
			|||||||
    <content url="file://$MODULE_DIR$">
 | 
					    <content url="file://$MODULE_DIR$">
 | 
				
			||||||
      <sourceFolder url="file://$MODULE_DIR$/nur_src" isTestSource="false" packagePrefix="nur\" />
 | 
					      <sourceFolder url="file://$MODULE_DIR$/nur_src" isTestSource="false" packagePrefix="nur\" />
 | 
				
			||||||
      <sourceFolder url="file://$MODULE_DIR$/nur_tests" isTestSource="true" packagePrefix="nur\" />
 | 
					      <sourceFolder url="file://$MODULE_DIR$/nur_tests" isTestSource="true" packagePrefix="nur\" />
 | 
				
			||||||
      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="nur\sery\wip\" />
 | 
					      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="nulib\" />
 | 
				
			||||||
      <sourceFolder url="file://$MODULE_DIR$/src_app" isTestSource="false" packagePrefix="nur\sery\" />
 | 
					      <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="nulib\" />
 | 
				
			||||||
      <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="nur\sery\" />
 | 
					 | 
				
			||||||
      <sourceFolder url="file://$MODULE_DIR$/src_glue" isTestSource="false" packagePrefix="nulib\" />
 | 
					 | 
				
			||||||
      <excludeFolder url="file://$MODULE_DIR$/vendor" />
 | 
					      <excludeFolder url="file://$MODULE_DIR$/vendor" />
 | 
				
			||||||
    </content>
 | 
					    </content>
 | 
				
			||||||
    <orderEntry type="inheritedJdk" />
 | 
					    <orderEntry type="inheritedJdk" />
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								CHANGES.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								CHANGES.md
									
									
									
									
									
								
							@ -1,3 +1,14 @@
 | 
				
			|||||||
 | 
					## Release 0.5.0p74 du 30/04/2025-05:30
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `2d73f4d` documenter showmorePlugin
 | 
				
			||||||
 | 
					* `3b13ef1` possiblité de forcer la suppression
 | 
				
			||||||
 | 
					* `3933fd1` corrections sur les controles
 | 
				
			||||||
 | 
					* `4d238cc` maj doc
 | 
				
			||||||
 | 
					* `f005692` déplacer nur/sery/wip et nur/sery dans nulib
 | 
				
			||||||
 | 
					* `c4e02d5` afficher la version de l'application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Release 0.4.1p82 du 17/03/2025-17:23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Release 0.4.1p74 du 17/03/2025-17:19
 | 
					## Release 0.4.1p74 du 17/03/2025-17:19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `56fda96` changer le type de variables gérées par EnvConfig
 | 
					* `56fda96` changer le type de variables gérées par EnvConfig
 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1 @@
 | 
				
			|||||||
0.4.1
 | 
					0.5.0
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										7
									
								
								bin/json2yml.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								bin/json2yml.php
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/php
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\tools\Json2yamlApp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Json2yamlApp::run();
 | 
				
			||||||
							
								
								
									
										7
									
								
								bin/yml2json.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								bin/yml2json.php
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/php
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\tools\Yaml2jsonApp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Yaml2jsonApp::run();
 | 
				
			||||||
@ -18,9 +18,9 @@
 | 
				
			|||||||
		"php": "^7.4"
 | 
							"php": "^7.4"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"require-dev": {
 | 
						"require-dev": {
 | 
				
			||||||
		"nulib/php": "^0.4.0p74",
 | 
							"nulib/php": "^0.5.0p74",
 | 
				
			||||||
		"nulib/spout": "^0.4.0p74",
 | 
							"nulib/spout": "^0.5.0p74",
 | 
				
			||||||
		"nulib/phpss": "^0.4.0p74",
 | 
							"nulib/phpss": "^0.5.0p74",
 | 
				
			||||||
		"nulib/tests": "^7.4",
 | 
							"nulib/tests": "^7.4",
 | 
				
			||||||
		"ext-posix": "*",
 | 
							"ext-posix": "*",
 | 
				
			||||||
		"ext-pcntl": "*",
 | 
							"ext-pcntl": "*",
 | 
				
			||||||
@ -52,9 +52,7 @@
 | 
				
			|||||||
	},
 | 
						},
 | 
				
			||||||
	"autoload": {
 | 
						"autoload": {
 | 
				
			||||||
		"psr-4": {
 | 
							"psr-4": {
 | 
				
			||||||
			"nulib\\": "src_glue",
 | 
								"nulib\\": "src",
 | 
				
			||||||
			"nur\\sery\\wip\\": "src",
 | 
					 | 
				
			||||||
			"nur\\sery\\": "src_app",
 | 
					 | 
				
			||||||
			"nur\\": "nur_src"
 | 
								"nur\\": "nur_src"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"files": [
 | 
							"files": [
 | 
				
			||||||
@ -63,13 +61,15 @@
 | 
				
			|||||||
	},
 | 
						},
 | 
				
			||||||
	"autoload-dev": {
 | 
						"autoload-dev": {
 | 
				
			||||||
		"psr-4": {
 | 
							"psr-4": {
 | 
				
			||||||
			"nur\\sery\\": "tests",
 | 
								"nulib\\": "tests",
 | 
				
			||||||
			"nur\\": "nur_tests"
 | 
								"nur\\": "nur_tests"
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"bin": [
 | 
						"bin": [
 | 
				
			||||||
		"bin/dumpser.php",
 | 
							"bin/dumpser.php",
 | 
				
			||||||
		"bin/csv2xlsx.php",
 | 
							"bin/csv2xlsx.php",
 | 
				
			||||||
 | 
							"bin/json2yml.php",
 | 
				
			||||||
 | 
							"bin/yml2json.php",
 | 
				
			||||||
		"nur_bin/compctl.php",
 | 
							"nur_bin/compctl.php",
 | 
				
			||||||
		"nur_bin/compdep.php",
 | 
							"nur_bin/compdep.php",
 | 
				
			||||||
		"nur_bin/datectl.php",
 | 
							"nur_bin/datectl.php",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										38
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@ -4,7 +4,7 @@
 | 
				
			|||||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
					        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
				
			||||||
        "This file is @generated automatically"
 | 
					        "This file is @generated automatically"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "content-hash": "85c16d446d9a6899358782f7520bf3f6",
 | 
					    "content-hash": "b4bd340f94d33a320d66b249b1c21edb",
 | 
				
			||||||
    "packages": [],
 | 
					    "packages": [],
 | 
				
			||||||
    "packages-dev": [
 | 
					    "packages-dev": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -404,16 +404,16 @@
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "myclabs/deep-copy",
 | 
					            "name": "myclabs/deep-copy",
 | 
				
			||||||
            "version": "1.13.0",
 | 
					            "version": "1.13.1",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://github.com/myclabs/DeepCopy.git",
 | 
					                "url": "https://github.com/myclabs/DeepCopy.git",
 | 
				
			||||||
                "reference": "024473a478be9df5fdaca2c793f2232fe788e414"
 | 
					                "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "dist": {
 | 
					            "dist": {
 | 
				
			||||||
                "type": "zip",
 | 
					                "type": "zip",
 | 
				
			||||||
                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414",
 | 
					                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c",
 | 
				
			||||||
                "reference": "024473a478be9df5fdaca2c793f2232fe788e414",
 | 
					                "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c",
 | 
				
			||||||
                "shasum": ""
 | 
					                "shasum": ""
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
@ -452,7 +452,7 @@
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "support": {
 | 
					            "support": {
 | 
				
			||||||
                "issues": "https://github.com/myclabs/DeepCopy/issues",
 | 
					                "issues": "https://github.com/myclabs/DeepCopy/issues",
 | 
				
			||||||
                "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0"
 | 
					                "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "funding": [
 | 
					            "funding": [
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@ -460,7 +460,7 @@
 | 
				
			|||||||
                    "type": "tidelift"
 | 
					                    "type": "tidelift"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2025-02-12T12:17:51+00:00"
 | 
					            "time": "2025-04-29T12:36:36+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "myclabs/php-enum",
 | 
					            "name": "myclabs/php-enum",
 | 
				
			||||||
@ -585,11 +585,11 @@
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "nulib/php",
 | 
					            "name": "nulib/php",
 | 
				
			||||||
            "version": "0.4.0p74",
 | 
					            "version": "0.5.0p74",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://git.univ-reunion.fr/sda-php/nulib.git",
 | 
					                "url": "https://git.univ-reunion.fr/sda-php/nulib.git",
 | 
				
			||||||
                "reference": "559feda663fc99f8baee2ba32f164b19bdd01927"
 | 
					                "reference": "4037bf20424eb48708e5fdf9fc8e10f2ef71d134"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
                "ext-json": "*",
 | 
					                "ext-json": "*",
 | 
				
			||||||
@ -599,6 +599,8 @@
 | 
				
			|||||||
            "require-dev": {
 | 
					            "require-dev": {
 | 
				
			||||||
                "ext-curl": "*",
 | 
					                "ext-curl": "*",
 | 
				
			||||||
                "ext-pcntl": "*",
 | 
					                "ext-pcntl": "*",
 | 
				
			||||||
 | 
					                "ext-pdo": "*",
 | 
				
			||||||
 | 
					                "ext-pgsql": "*",
 | 
				
			||||||
                "ext-posix": "*",
 | 
					                "ext-posix": "*",
 | 
				
			||||||
                "ext-sqlite3": "*",
 | 
					                "ext-sqlite3": "*",
 | 
				
			||||||
                "nulib/tests": "^7.4"
 | 
					                "nulib/tests": "^7.4"
 | 
				
			||||||
@ -627,18 +629,18 @@
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "description": "fonctions et classes essentielles",
 | 
					            "description": "fonctions et classes essentielles",
 | 
				
			||||||
            "time": "2025-03-14T11:23:41+00:00"
 | 
					            "time": "2025-04-30T00:32:10+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "nulib/phpss",
 | 
					            "name": "nulib/phpss",
 | 
				
			||||||
            "version": "0.4.0p74",
 | 
					            "version": "0.5.0p74",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://git.univ-reunion.fr/sda-php/nulib-phpss.git",
 | 
					                "url": "https://git.univ-reunion.fr/sda-php/nulib-phpss.git",
 | 
				
			||||||
                "reference": "1d8a88039f17242c72ff20cd01538b3fce8f8692"
 | 
					                "reference": "26b4bfddf5646f9313d419e568cd930efb9353eb"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
                "nulib/php": "^0.4.0p74",
 | 
					                "nulib/php": "^0.5.0p74",
 | 
				
			||||||
                "php": "^7.4",
 | 
					                "php": "^7.4",
 | 
				
			||||||
                "phpoffice/phpspreadsheet": "^1.0"
 | 
					                "phpoffice/phpspreadsheet": "^1.0"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
@ -669,15 +671,15 @@
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "description": "wrapper pour phpoffice/phpspreadsheet",
 | 
					            "description": "wrapper pour phpoffice/phpspreadsheet",
 | 
				
			||||||
            "time": "2025-03-14T11:28:01+00:00"
 | 
					            "time": "2025-04-30T00:46:31+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "nulib/spout",
 | 
					            "name": "nulib/spout",
 | 
				
			||||||
            "version": "0.4.0p74",
 | 
					            "version": "0.5.0p74",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://git.univ-reunion.fr/sda-php/nulib-spout.git",
 | 
					                "url": "https://git.univ-reunion.fr/sda-php/nulib-spout.git",
 | 
				
			||||||
                "reference": "b5836e61961838c7f6d6735cdb671d47e05315e0"
 | 
					                "reference": "e650e27abe571553424524633deada32747d33a6"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
                "ext-dom": "*",
 | 
					                "ext-dom": "*",
 | 
				
			||||||
@ -685,7 +687,7 @@
 | 
				
			|||||||
                "ext-libxml": "*",
 | 
					                "ext-libxml": "*",
 | 
				
			||||||
                "ext-xmlreader": "*",
 | 
					                "ext-xmlreader": "*",
 | 
				
			||||||
                "ext-zip": "*",
 | 
					                "ext-zip": "*",
 | 
				
			||||||
                "nulib/php": "^0.4.0p74",
 | 
					                "nulib/php": "^0.5.0p74",
 | 
				
			||||||
                "php": "^7.4"
 | 
					                "php": "^7.4"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "replace": {
 | 
					            "replace": {
 | 
				
			||||||
@ -723,7 +725,7 @@
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "description": "wrapper pour openspout/openspout",
 | 
					            "description": "wrapper pour openspout/openspout",
 | 
				
			||||||
            "time": "2025-03-14T11:36:53+00:00"
 | 
					            "time": "2025-04-30T00:40:11+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "nulib/tests",
 | 
					            "name": "nulib/tests",
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,6 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
					require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\tools\SteamTrainApp;
 | 
					use nulib\tools\SteamTrainApp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SteamTrainApp::run();
 | 
					SteamTrainApp::run();
 | 
				
			||||||
 | 
				
			|||||||
@ -287,10 +287,10 @@ abstract class FileCachedValue extends Parametrable implements ArrayAccess, Coun
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** supprimer le fichier s'il a expiré */
 | 
					  /** supprimer le fichier s'il a expiré */
 | 
				
			||||||
  function deleteExpired(): bool {
 | 
					  function deleteExpired(bool $force=false): bool {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      if ($this->shouldUpdate()) {
 | 
					      if ($force || $this->shouldUpdate()) {
 | 
				
			||||||
        unlink($this->ppFile);
 | 
					        @unlink($this->ppFile);
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } finally {
 | 
					    } finally {
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
namespace nur\cli;
 | 
					namespace nur\cli;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Exception;
 | 
					use Exception;
 | 
				
			||||||
 | 
					use nulib\app;
 | 
				
			||||||
use nulib\app\RunFile;
 | 
					use nulib\app\RunFile;
 | 
				
			||||||
use nulib\ExitError;
 | 
					use nulib\ExitError;
 | 
				
			||||||
use nulib\ext\yaml;
 | 
					use nulib\ext\yaml;
 | 
				
			||||||
@ -16,7 +17,6 @@ use nur\config\ArrayConfig;
 | 
				
			|||||||
use nur\msg;
 | 
					use nur\msg;
 | 
				
			||||||
use nur\os;
 | 
					use nur\os;
 | 
				
			||||||
use nur\path;
 | 
					use nur\path;
 | 
				
			||||||
use nur\sery\app;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class Application: application de base
 | 
					 * Class Application: application de base
 | 
				
			||||||
 | 
				
			|||||||
@ -105,7 +105,7 @@ class ref_type {
 | 
				
			|||||||
  /** comme {@link c} mais nullable */
 | 
					  /** comme {@link c} mais nullable */
 | 
				
			||||||
  const NCONTENT = "?".self::CONTENT;
 | 
					  const NCONTENT = "?".self::CONTENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** comme {@link \nur\sery\FILE} mais nullable */
 | 
					  /** comme {@link FILE} mais nullable */
 | 
				
			||||||
  const NFILE = "?".self::FILE;
 | 
					  const NFILE = "?".self::FILE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** comme {@link DATETIME} mais nullable */
 | 
					  /** comme {@link DATETIME} mais nullable */
 | 
				
			||||||
 | 
				
			|||||||
@ -599,16 +599,16 @@ class Form extends ComponentPrintable implements IParametrable, ArrayAccess, Cou
 | 
				
			|||||||
  /** @var ?array */
 | 
					  /** @var ?array */
 | 
				
			||||||
  protected $hiddenControls;
 | 
					  protected $hiddenControls;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function addHiddenControl($control, ?string $name=null): self {
 | 
					  function addHiddenControl($control, ?string $id=null): self {
 | 
				
			||||||
    A::set($this->hiddenControls, $name, $control);
 | 
					    A::set($this->hiddenControls, $id, $control);
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @var ?array */
 | 
					  /** @var ?array */
 | 
				
			||||||
  protected $controls;
 | 
					  protected $controls;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function addControl($control, ?string $name=null): self {
 | 
					  function addControl($control, ?string $id=null): self {
 | 
				
			||||||
    A::set($this->controls, $name, $control);
 | 
					    A::set($this->controls, $id, $control);
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -660,7 +660,8 @@ class Form extends ComponentPrintable implements IParametrable, ArrayAccess, Cou
 | 
				
			|||||||
      $param["value"] = $value;
 | 
					      $param["value"] = $value;
 | 
				
			||||||
      #XXX en attendant le formattage ci-dessus, forcer la format texte pour que
 | 
					      #XXX en attendant le formattage ci-dessus, forcer la format texte pour que
 | 
				
			||||||
      # la comparaison puisse se faire
 | 
					      # la comparaison puisse se faire
 | 
				
			||||||
      $param["checked"] = strval($currentValue) === strval($value);
 | 
					      #XXX si $name est un tableau e.g values[] le test ci-dessous ne fonctionne pas
 | 
				
			||||||
 | 
					      $param["checked"] ??= strval($currentValue) === strval($value);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case self::NV:
 | 
					    case self::NV:
 | 
				
			||||||
      if ($value === null) $value = $this->get($key, $default);
 | 
					      if ($value === null) $value = $this->get($key, $default);
 | 
				
			||||||
@ -672,7 +673,7 @@ class Form extends ComponentPrintable implements IParametrable, ArrayAccess, Cou
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if ($params === null) $params = $param;
 | 
					    if ($params === null) $params = $param;
 | 
				
			||||||
    else A::update_n($params, $param);
 | 
					    else A::update_n($params, $param);
 | 
				
			||||||
    return [new $controlClass($this, $params), $name];
 | 
					    return [new $controlClass($this, $params), $key];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private function _prepareControls(): ?array {
 | 
					  private function _prepareControls(): ?array {
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,7 @@ class nb {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static final function menu($text, ?array $links=null, ?array $options=null): array {
 | 
					  static final function menu($text, ?array $links=null, ?array $options=null): array {
 | 
				
			||||||
 | 
					    $links = array_filter($links, function($link) { return $link !== null; });
 | 
				
			||||||
    $item = ["item" => "menu", "links" => $links, "value" => $text];
 | 
					    $item = ["item" => "menu", "links" => $links, "value" => $text];
 | 
				
			||||||
    if ($options !== null) $item = array_merge($item, $options);
 | 
					    if ($options !== null) $item = array_merge($item, $options);
 | 
				
			||||||
    return $item;
 | 
					    return $item;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,23 @@ use nur\v\BasePlugin;
 | 
				
			|||||||
use nur\v\v;
 | 
					use nur\v\v;
 | 
				
			||||||
use nur\v\vo;
 | 
					use nur\v\vo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class showmorePlugin: un outil pour masquer par défaut un panneau de détails
 | 
				
			||||||
 | 
					 * et donner la possibilité à l'utilisateur de l'afficher
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * s'utilise de cette façon:
 | 
				
			||||||
 | 
					 * <pre>
 | 
				
			||||||
 | 
					 * $sm = new showmorePlugin();
 | 
				
			||||||
 | 
					 * // le tout doit être dans le container startc-endc
 | 
				
			||||||
 | 
					 * $sm->printStartc();
 | 
				
			||||||
 | 
					 * // l'invite contient un lien pour afficher le panneau caché
 | 
				
			||||||
 | 
					 * $sm->printInvite();
 | 
				
			||||||
 | 
					 * // le panneau caché est dans le container startp-endp
 | 
				
			||||||
 | 
					 * $sm->printStartp();
 | 
				
			||||||
 | 
					 * $sm->printEndp();
 | 
				
			||||||
 | 
					 * $sm->printEndc();
 | 
				
			||||||
 | 
					 * </pre>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class showmorePlugin extends BasePlugin {
 | 
					class showmorePlugin extends BasePlugin {
 | 
				
			||||||
  const HAVE_JQUERY = true;
 | 
					  const HAVE_JQUERY = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\v\vp;
 | 
					namespace nur\v\vp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\app;
 | 
				
			||||||
use nur\authz;
 | 
					use nur\authz;
 | 
				
			||||||
use nur\b\authnz\IAuthzUser;
 | 
					use nur\b\authnz\IAuthzUser;
 | 
				
			||||||
use nur\config;
 | 
					use nur\config;
 | 
				
			||||||
@ -46,6 +47,21 @@ class NavigablePage extends AInitAuthzPage implements INavigablePage {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  const MENU_SULOGIN = true;
 | 
					  const MENU_SULOGIN = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function getAppVersionNbtext(): ?array {
 | 
				
			||||||
 | 
					    $app = app::get();
 | 
				
			||||||
 | 
					    $projdir = $app->getProjdir();
 | 
				
			||||||
 | 
					    $versionfile =  "$projdir/VERSION.txt";
 | 
				
			||||||
 | 
					    if (file_exists($versionfile)) {
 | 
				
			||||||
 | 
					      $name = $app->getName();
 | 
				
			||||||
 | 
					      $version = file_get_contents($versionfile);
 | 
				
			||||||
 | 
					      return nb::text([
 | 
				
			||||||
 | 
					        "style" => "margin: 0 15px",
 | 
				
			||||||
 | 
					        "$name v$version"
 | 
				
			||||||
 | 
					      ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function getAuthzNbtext(IAuthzUser $user): array {
 | 
					  protected function getAuthzNbtext(IAuthzUser $user): array {
 | 
				
			||||||
    $username = $user->getUsername();
 | 
					    $username = $user->getUsername();
 | 
				
			||||||
    $role = $user->getRole();
 | 
					    $role = $user->getRole();
 | 
				
			||||||
@ -95,6 +111,7 @@ class NavigablePage extends AInitAuthzPage implements INavigablePage {
 | 
				
			|||||||
      $user = authz::get();
 | 
					      $user = authz::get();
 | 
				
			||||||
      navbar::nav(["align" => "right"], [
 | 
					      navbar::nav(["align" => "right"], [
 | 
				
			||||||
        nb::menu(icon::user($user->getShortName()), [
 | 
					        nb::menu(icon::user($user->getShortName()), [
 | 
				
			||||||
 | 
					          $this->getAppVersionNbtext(),
 | 
				
			||||||
          $this->getAuthzNbtext($user),
 | 
					          $this->getAuthzNbtext($user),
 | 
				
			||||||
          $this->getLogoutNblink(),
 | 
					          $this->getLogoutNblink(),
 | 
				
			||||||
        ]),
 | 
					        ]),
 | 
				
			||||||
 | 
				
			|||||||
@ -2,7 +2,7 @@
 | 
				
			|||||||
require(__DIR__.'/../../vendor/autoload.php');
 | 
					require(__DIR__.'/../../vendor/autoload.php');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\cli\Application;
 | 
					use nur\cli\Application;
 | 
				
			||||||
use nur\sery\output\msg;
 | 
					use nulib\output\msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestArgs4 extends Application {
 | 
					class TestArgs4 extends Application {
 | 
				
			||||||
  protected $query;
 | 
					  protected $query;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,18 +1,13 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery;
 | 
					namespace nulib;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\A;
 | 
					use nulib\app\cli\Application;
 | 
				
			||||||
use nulib\app\LockFile;
 | 
					use nulib\app\LockFile;
 | 
				
			||||||
use nulib\app\RunFile;
 | 
					use nulib\app\RunFile;
 | 
				
			||||||
use nulib\cl;
 | 
					 | 
				
			||||||
use nulib\ExitError;
 | 
					 | 
				
			||||||
use nulib\os\path;
 | 
					use nulib\os\path;
 | 
				
			||||||
use nulib\os\sh;
 | 
					use nulib\os\sh;
 | 
				
			||||||
use nulib\php\func;
 | 
					use nulib\php\func;
 | 
				
			||||||
use nulib\str;
 | 
					 | 
				
			||||||
use nulib\ValueException;
 | 
					 | 
				
			||||||
use nur\cli\Application as nur_Application;
 | 
					use nur\cli\Application as nur_Application;
 | 
				
			||||||
use nur\sery\app\cli\Application;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class app {
 | 
					class app {
 | 
				
			||||||
  private static function isa_Application($app): bool {
 | 
					  private static function isa_Application($app): bool {
 | 
				
			||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\app\cli;
 | 
					namespace nulib\app\cli;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Exception;
 | 
					use Exception;
 | 
				
			||||||
 | 
					use nulib\app;
 | 
				
			||||||
use nulib\app\RunFile;
 | 
					use nulib\app\RunFile;
 | 
				
			||||||
use nulib\ExitError;
 | 
					use nulib\ExitError;
 | 
				
			||||||
use nulib\ext\yaml;
 | 
					use nulib\ext\yaml;
 | 
				
			||||||
@ -13,7 +14,6 @@ use nulib\ValueException;
 | 
				
			|||||||
use nur\cli\ArgsException;
 | 
					use nur\cli\ArgsException;
 | 
				
			||||||
use nur\cli\ArgsParser;
 | 
					use nur\cli\ArgsParser;
 | 
				
			||||||
use nur\config;
 | 
					use nur\config;
 | 
				
			||||||
use nur\sery\app;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class Application: application de base
 | 
					 * Class Application: application de base
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -8,6 +8,18 @@ use nulib\cl;
 | 
				
			|||||||
 * de {@link IAccess}
 | 
					 * de {@link IAccess}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
abstract class AbstractAccess implements IAccess {
 | 
					abstract class AbstractAccess implements IAccess {
 | 
				
			||||||
 | 
					  const ALLOW_EMPTY = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function __construct(?array $params=null) {
 | 
				
			||||||
 | 
					    $this->allowEmpty = $params["allow_empty"] ?? static::ALLOW_EMPTY;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected bool $allowEmpty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function isAllowEmpty(): bool {
 | 
				
			||||||
 | 
					    return $this->allowEmpty;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function inc(): int {
 | 
					  function inc(): int {
 | 
				
			||||||
    $value = (int)$this->get();
 | 
					    $value = (int)$this->get();
 | 
				
			||||||
    $this->set(++$value);
 | 
					    $this->set(++$value);
 | 
				
			||||||
@ -33,4 +45,16 @@ abstract class AbstractAccess implements IAccess {
 | 
				
			|||||||
    cl::set($array, $key, $value);
 | 
					    cl::set($array, $key, $value);
 | 
				
			||||||
    $this->set($array);
 | 
					    $this->set($array);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureAssoc(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function deleteMissings(array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureOrder(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								src/php/access/ArrayAccess.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/php/access/ArrayAccess.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ArrayAccess extends KeyAccess {
 | 
				
			||||||
 | 
					  const ALLOW_NULL = true;
 | 
				
			||||||
 | 
					  const ALLOW_FALSE = false;
 | 
				
			||||||
 | 
					  const PROTECT_DEST = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										182
									
								
								src/php/access/ChainAccess.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								src/php/access/ChainAccess.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,182 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\cl;
 | 
				
			||||||
 | 
					use nulib\StateException;
 | 
				
			||||||
 | 
					use ReflectionClass;
 | 
				
			||||||
 | 
					use ReflectionException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ChainAccess extends AbstractAccess {
 | 
				
			||||||
 | 
					  const ACCESS_AUTO = 0, ACCESS_KEY = 1, ACCESS_PROPERTY = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private static function unexpected_access_type(): StateException {
 | 
				
			||||||
 | 
					    return StateException::unexpected_state("access_type");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  function __construct(IAccess $access, $key, ?array $params=null) {
 | 
				
			||||||
 | 
					    parent::__construct();
 | 
				
			||||||
 | 
					    $this->access = $access;
 | 
				
			||||||
 | 
					    $this->key = $key;
 | 
				
			||||||
 | 
					    $this->accessType = $params["access_type"] ?? self::ACCESS_AUTO;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected IAccess $access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @var null|int|string|array */
 | 
				
			||||||
 | 
					  protected $key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected int $accessType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _accessType($access, $key): int {
 | 
				
			||||||
 | 
					    $accessType = $this->accessType;
 | 
				
			||||||
 | 
					    if ($accessType === self::ACCESS_AUTO) {
 | 
				
			||||||
 | 
					      if (is_object($access) && is_string($key)) {
 | 
				
			||||||
 | 
					        $accessType = self::ACCESS_PROPERTY;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        $accessType = self::ACCESS_KEY;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $accessType;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _has(): bool {
 | 
				
			||||||
 | 
					    $src = $this->access->get();
 | 
				
			||||||
 | 
					    $key = $this->key;
 | 
				
			||||||
 | 
					    $accessType = $this->_accessType($src, $key);
 | 
				
			||||||
 | 
					    if ($accessType === self::ACCESS_KEY) {
 | 
				
			||||||
 | 
					      return cl::phas($src, $key);
 | 
				
			||||||
 | 
					    } elseif ($accessType === self::ACCESS_PROPERTY) {
 | 
				
			||||||
 | 
					      $class = new ReflectionClass($src);
 | 
				
			||||||
 | 
					      return $class->hasProperty($key) || property_exists($src, $key);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      throw self::unexpected_access_type();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _get($default=null) {
 | 
				
			||||||
 | 
					    $src = $this->access->get();
 | 
				
			||||||
 | 
					    $key = $this->key;
 | 
				
			||||||
 | 
					    $accessType = $this->_accessType($src, $key);
 | 
				
			||||||
 | 
					    if ($accessType === self::ACCESS_KEY) {
 | 
				
			||||||
 | 
					      return cl::pget($src, $key);
 | 
				
			||||||
 | 
					    } elseif ($accessType === self::ACCESS_PROPERTY) {
 | 
				
			||||||
 | 
					      $class = new ReflectionClass($src);
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        $property = $class->getProperty($key);
 | 
				
			||||||
 | 
					        $property->setAccessible(true);
 | 
				
			||||||
 | 
					      } catch (ReflectionException $e) {
 | 
				
			||||||
 | 
					        $property = null;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if ($property !== null) {
 | 
				
			||||||
 | 
					        return $property->getValue($src);
 | 
				
			||||||
 | 
					      } elseif (property_exists($src, $key)) {
 | 
				
			||||||
 | 
					        return $src->$key;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return $default;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      throw self::unexpected_access_type();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _pset(object $dest, $name, $value): void {
 | 
				
			||||||
 | 
					    $class = new ReflectionClass($dest);
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      $property = $class->getProperty($name);
 | 
				
			||||||
 | 
					      $property->setAccessible(true);
 | 
				
			||||||
 | 
					    } catch (ReflectionException $e) {
 | 
				
			||||||
 | 
					      $property = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($property !== null) {
 | 
				
			||||||
 | 
					      $property->setValue($dest, $value);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $dest->$name = $value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function isAllowEmpty(): bool {
 | 
				
			||||||
 | 
					    return $this->access->isAllowEmpty();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function exists(): bool {
 | 
				
			||||||
 | 
					    if (!$this->access->exists()) return false;
 | 
				
			||||||
 | 
					    if ($this->key === null) return true;
 | 
				
			||||||
 | 
					    return $this->_has();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function available(): bool {
 | 
				
			||||||
 | 
					    if (!$this->access->available()) return false;
 | 
				
			||||||
 | 
					    if ($this->key === null) return true;
 | 
				
			||||||
 | 
					    if (!$this->_has()) return false;
 | 
				
			||||||
 | 
					    return $this->isAllowEmpty() || $this->_get() !== "";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function get($default=null) {
 | 
				
			||||||
 | 
					    if ($this->key === null) {
 | 
				
			||||||
 | 
					      return $this->access->get($default);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $this->_get($default);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function set($value): void {
 | 
				
			||||||
 | 
					    if ($this->key === null) {
 | 
				
			||||||
 | 
					      $this->access->set($value);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $dest = $this->access->get();
 | 
				
			||||||
 | 
					    $key = $this->key;
 | 
				
			||||||
 | 
					    $accessType = $this->_accessType($dest, $key);
 | 
				
			||||||
 | 
					    if ($accessType === self::ACCESS_KEY) {
 | 
				
			||||||
 | 
					      cl::pset($dest, $key, $value);
 | 
				
			||||||
 | 
					      $this->access->set($dest);
 | 
				
			||||||
 | 
					    } elseif ($accessType === self::ACCESS_PROPERTY) {
 | 
				
			||||||
 | 
					      $this->_pset($dest, $key, $value);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      throw self::unexpected_access_type();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function del(): void {
 | 
				
			||||||
 | 
					    if ($this->key === null) {
 | 
				
			||||||
 | 
					      $this->access->del();
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $dest = $this->access->get();
 | 
				
			||||||
 | 
					    $key = $this->key;
 | 
				
			||||||
 | 
					    $accessType = $this->_accessType($dest, $key);
 | 
				
			||||||
 | 
					    if ($accessType === self::ACCESS_KEY) {
 | 
				
			||||||
 | 
					      cl::pdel($dest, $key);
 | 
				
			||||||
 | 
					      $this->access->set($dest);
 | 
				
			||||||
 | 
					    } elseif ($accessType === self::ACCESS_PROPERTY) {
 | 
				
			||||||
 | 
					      $this->_pset($dest, $key, null);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      throw self::unexpected_access_type();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addKey($key, ?array $params=null): IAccess {
 | 
				
			||||||
 | 
					    if ($key === null) return $this;
 | 
				
			||||||
 | 
					    $accessType = $params["access_type"] ?? $this->accessType;
 | 
				
			||||||
 | 
					    if ($accessType === self::ACCESS_KEY && $accessType === $this->accessType) {
 | 
				
			||||||
 | 
					      if ($this->key !== null) $key = cl::merge($this->key, $key);
 | 
				
			||||||
 | 
					      return new ChainAccess($this->access, $key);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return new ChainAccess($this, $key);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureAssoc(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    #XXX fonction de $accessType?
 | 
				
			||||||
 | 
					    #$this->access->ensureAssoc($keys, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					    #XXX fonction de $accessType?
 | 
				
			||||||
 | 
					    #$this->access->ensureKeys($defaults, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureOrder(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    #XXX fonction de $accessType?
 | 
				
			||||||
 | 
					    #$this->access->ensureOrder($keys, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -7,67 +7,99 @@ use nulib\cl;
 | 
				
			|||||||
 * Class FormAccess: accès à une valeur de $_POST puis $_GET, dans cet ordre
 | 
					 * Class FormAccess: accès à une valeur de $_POST puis $_GET, dans cet ordre
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class FormAccess extends AbstractAccess {
 | 
					class FormAccess extends AbstractAccess {
 | 
				
			||||||
 | 
					  const ALLOW_EMPTY = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function __construct($key, ?array $params=null) {
 | 
					  function __construct($key, ?array $params=null) {
 | 
				
			||||||
 | 
					    parent::__construct($params);
 | 
				
			||||||
    $this->key = $key;
 | 
					    $this->key = $key;
 | 
				
			||||||
    $this->allowEmpty = $params["allow_empty"] ?? false;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @var int|string */
 | 
					  /** @var null|int|string|array */
 | 
				
			||||||
  protected $key;
 | 
					  protected $key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected bool $allowEmpty;
 | 
					  protected function _exists(array $first, ?array $second=null): bool {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  function exists(): bool {
 | 
					 | 
				
			||||||
    $key = $this->key;
 | 
					    $key = $this->key;
 | 
				
			||||||
    if ($key === null) return false;
 | 
					    if ($key === null) return true;
 | 
				
			||||||
    return array_key_exists($key, $_POST) || array_key_exists($key, $_GET);
 | 
					    if (cl::phas($first, $key)) return true;
 | 
				
			||||||
 | 
					    return $second !== null && cl::phas($second, $key);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function available(): bool {
 | 
					  function exists(): bool {
 | 
				
			||||||
 | 
					    return $this->_exists($_POST, $_GET);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _available(array $first, ?array $second=null): bool {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $key = $this->key;
 | 
				
			||||||
    if ($key === null) return false;
 | 
					    if ($key === null) return true;
 | 
				
			||||||
    if (array_key_exists($key, $_POST)) {
 | 
					    if (cl::phas($first, $key)) {
 | 
				
			||||||
      return $this->allowEmpty || $_POST[$key] !== "";
 | 
					      return $this->allowEmpty || cl::pget($first, $key) !== "";
 | 
				
			||||||
    } elseif (array_key_exists($key, $_GET)) {
 | 
					    } elseif ($second !== null && cl::phas($second, $key)) {
 | 
				
			||||||
      return $this->allowEmpty || $_GET[$key] !== "";
 | 
					      return $this->allowEmpty || cl::pget($second, $key) !== "";
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return false;
 | 
					      return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get($default=null) {
 | 
					  public function available(): bool {
 | 
				
			||||||
 | 
					    return $this->_available($_POST, $_GET);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _get($default, array $first, ?array $second=null) {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $key = $this->key;
 | 
				
			||||||
    if ($key === null) return $default;
 | 
					    if ($key === null) return cl::merge($first, $second);
 | 
				
			||||||
    if (array_key_exists($key, $_POST)) {
 | 
					    if (cl::phas($first, $key)) {
 | 
				
			||||||
      $value = $_POST[$key];
 | 
					      $value = cl::pget($first, $key);
 | 
				
			||||||
      if ($value === "" && !$this->allowEmpty) return $default;
 | 
					      if ($value !== "" || $this->allowEmpty) return $value;
 | 
				
			||||||
      return $value;
 | 
					    } elseif ($second !== null && cl::phas($second, $key)) {
 | 
				
			||||||
    } elseif (array_key_exists($key, $_GET)) {
 | 
					      $value = cl::pget($second, $key);
 | 
				
			||||||
      $value = $_GET[$key];
 | 
					      if ($value !== "" || $this->allowEmpty) return $value;
 | 
				
			||||||
      if ($value === "" && !$this->allowEmpty) return $default;
 | 
					    }
 | 
				
			||||||
      return $value;
 | 
					    return $default;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function get($default=null) {
 | 
				
			||||||
 | 
					    return $this->_get($default, $_POST, $_GET);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function _set($value, array &$first, ?array &$second=null): void {
 | 
				
			||||||
 | 
					    $key = $this->key;
 | 
				
			||||||
 | 
					    if ($key === null) {
 | 
				
			||||||
 | 
					      # interdire la modification de la destination
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($second !== null && !cl::phas($first, $key) && cl::phas($second, $key)) {
 | 
				
			||||||
 | 
					      cl::pset($second, $key, $value);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return $default;
 | 
					      cl::pset($first, $key, $value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function set($value): void {
 | 
					  function set($value): void {
 | 
				
			||||||
 | 
					    $this->_set($value, $_POST, $_GET);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function _del(array &$first, ?array &$second=null): void {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $key = $this->key;
 | 
				
			||||||
    if ($key === null) return;
 | 
					    if ($key === null) {
 | 
				
			||||||
    if (!array_key_exists($key, $_POST) && array_key_exists($key, $_GET)) {
 | 
					      # interdire la modification de la destination
 | 
				
			||||||
      cl::set($_GET, $key, $value);
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($second !== null && !cl::phas($first, $key) && cl::phas($second, $key)) {
 | 
				
			||||||
 | 
					      cl::pdel($second, $key);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      cl::set($_POST, $key, $value);
 | 
					      cl::pdel($first, $key);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function del(): void {
 | 
					  function del(): void {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $this->_del($_POST, $_GET);
 | 
				
			||||||
    if ($key === null) return;
 | 
					  }
 | 
				
			||||||
    if (!array_key_exists($key, $_POST) && array_key_exists($key, $_GET)) {
 | 
					
 | 
				
			||||||
      cl::del($_GET, $key);
 | 
					  function addKey($key): self {
 | 
				
			||||||
    } else {
 | 
					    if ($key === null) return $this;
 | 
				
			||||||
      cl::del($_POST, $key);
 | 
					    if ($this->key !== null) $key = cl::merge($this->key, $key);
 | 
				
			||||||
    }
 | 
					    return new static($key, [
 | 
				
			||||||
 | 
					      "allow_empty" => $this->allowEmpty
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,49 +1,27 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					 | 
				
			||||||
use nulib\cl;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class GetAccess: accès à une valeur de $_GET
 | 
					 * Class GetAccess: accès à une valeur de $_GET
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class GetAccess extends FormAccess {
 | 
					class GetAccess extends FormAccess {
 | 
				
			||||||
  function exists(): bool {
 | 
					  function exists(): bool {
 | 
				
			||||||
    $key = $this->key;
 | 
					    return $this->_exists($_GET);
 | 
				
			||||||
    if ($key === null) return false;
 | 
					 | 
				
			||||||
    return array_key_exists($key, $_GET);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function available(): bool {
 | 
					  public function available(): bool {
 | 
				
			||||||
    $key = $this->key;
 | 
					    return $this->_available($_GET);
 | 
				
			||||||
    if ($key === null) return false;
 | 
					 | 
				
			||||||
    if (array_key_exists($key, $_GET)) {
 | 
					 | 
				
			||||||
      return $this->allowEmpty || $_GET[$key] !== "";
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get($default=null) {
 | 
					  function get($default=null) {
 | 
				
			||||||
    $key = $this->key;
 | 
					    return $this->_get($default, $_GET);
 | 
				
			||||||
    if ($key === null) return $default;
 | 
					 | 
				
			||||||
    if (array_key_exists($key, $_GET)) {
 | 
					 | 
				
			||||||
      $value = $_GET[$key];
 | 
					 | 
				
			||||||
      if ($value === "" && !$this->allowEmpty) return $default;
 | 
					 | 
				
			||||||
      return $value;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return $default;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function set($value): void {
 | 
					  function set($value): void {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $this->_set($value, $_GET);
 | 
				
			||||||
    if ($key === null) return;
 | 
					 | 
				
			||||||
    cl::set($_GET, $key, $value);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function del(): void {
 | 
					  function del(): void {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $this->_del($_GET);
 | 
				
			||||||
    if ($key === null) return;
 | 
					 | 
				
			||||||
    cl::del($_GET, $key);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Interface IAccess: abstraction d'un accès complet à une valeur
 | 
					 * Interface IAccess: abstraction d'un accès complet à une valeur
 | 
				
			||||||
@ -25,4 +25,32 @@ interface IAccess extends IGetter, ISetter, IDeleter {
 | 
				
			|||||||
   * tableau si $key===null
 | 
					   * tableau si $key===null
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function append($value, $key=null): void;
 | 
					  function append($value, $key=null): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** retourner une instance permettant d'accéder à $value[$key] */
 | 
				
			||||||
 | 
					  function addKey($key): IAccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * s'assurer que la destination est un tableau associatif en remplaçant les
 | 
				
			||||||
 | 
					   * clés numériques par les clés correspondantes du tableau $keys
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function ensureAssoc(array $keys, ?array $params=null): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * s'assurer que toutes les clés mentionnées dans le tableau $defaults
 | 
				
			||||||
 | 
					   * existent. si elles n'existent pas, ou si elles ont la valeur correspondante
 | 
				
			||||||
 | 
					   * du tableau $missings, leur donner la valeur du tableau $defaults
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * supprimer toutes les clés dont la valeur est celle mentionnée dans le
 | 
				
			||||||
 | 
					   * tableau $missings
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function deleteMissings(array $missings, ?array $params=null): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * s'assure que les clés de la destination sont dans l'ordre mentionné dans le
 | 
				
			||||||
 | 
					   * tableau $keys. toutes les clés supplémentaires sont placées à la fin
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function ensureOrder(array $keys, ?array $params=null): void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class IDeleter: une abstraction d'un objet qui permet de supprimer une valeur
 | 
					 * Class IDeleter: une abstraction d'un objet qui permet de supprimer une valeur
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class IGetter: une abstraction d'un objet qui permet d'obtenir une valeur
 | 
					 * Class IGetter: une abstraction d'un objet qui permet d'obtenir une valeur
 | 
				
			||||||
@ -11,6 +11,12 @@ interface IGetter {
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  function exists(): bool;
 | 
					  function exists(): bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * @return bool true si cet objet autorise les chaines vides. si c'est le cas,
 | 
				
			||||||
 | 
					   * {@link exists()} et {@link available()} sont fonctionnellement identiques
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function isAllowEmpty(): bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @return bool true si la valeur existe et est utilisable, false sinon */
 | 
					  /** @return bool true si la valeur existe et est utilisable, false sinon */
 | 
				
			||||||
  function available(): bool;
 | 
					  function available(): bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class ISetter: une abstraction d'un objet qui permet de modifier une valeur
 | 
					 * Class ISetter: une abstraction d'un objet qui permet de modifier une valeur
 | 
				
			||||||
 | 
				
			|||||||
@ -1,69 +1,202 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use ArrayAccess;
 | 
					use ArrayAccess;
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class KeyAccess: accès à une valeur d'une clé dans un tableau
 | 
					 * Class KeyAccess: accès
 | 
				
			||||||
 | 
					 * - soit à une valeur d'un chemin de clé dans un tableau (si $key !== null)
 | 
				
			||||||
 | 
					 * - soit à une valeur scalaire (si $key === null)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class KeyAccess extends AbstractAccess {
 | 
					class KeyAccess extends AbstractAccess {
 | 
				
			||||||
  function __construct(&$array, $key, ?array $params=null) {
 | 
					  const ALLOW_NULL = null;
 | 
				
			||||||
    $this->array =& $array;
 | 
					  const ALLOW_FALSE = null;
 | 
				
			||||||
 | 
					  const PROTECT_DEST = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function __construct(&$dest, $key=null, ?array $params=null) {
 | 
				
			||||||
 | 
					    parent::__construct($params);
 | 
				
			||||||
 | 
					    $this->protectDest = $params["protect_dest"] ?? static::PROTECT_DEST;
 | 
				
			||||||
 | 
					    $this->dest =& $dest;
 | 
				
			||||||
    $this->key = $key;
 | 
					    $this->key = $key;
 | 
				
			||||||
    $this->allowNull = $params["allow_null"] ?? true;
 | 
					    $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL;
 | 
				
			||||||
    $this->allowFalse = $params["allow_false"] ?? false;
 | 
					    $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE;
 | 
				
			||||||
    $this->allowEmpty = $params["allow_empty"] ?? true;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @var array|ArrayAccess */
 | 
					  protected bool $protectDest;
 | 
				
			||||||
  protected $array;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function reset(&$array): self {
 | 
					  /** @var mixed|array|ArrayAccess */
 | 
				
			||||||
    $this->array =& $array;
 | 
					  protected $dest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @var null|int|string|array */
 | 
				
			||||||
 | 
					  protected $key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function reset(&$dest, $key=null): self {
 | 
				
			||||||
 | 
					    $this->dest =& $dest;
 | 
				
			||||||
 | 
					    $this->key = $key;
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @var int|string */
 | 
					  function resetKey($key=null): self {
 | 
				
			||||||
  protected $key;
 | 
					    $this->key = $key;
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected bool $allowNull;
 | 
					  protected ?bool $allowNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected bool $allowFalse;
 | 
					  protected function isAllowNull(): bool {
 | 
				
			||||||
 | 
					    $allowNull = $this->allowNull;
 | 
				
			||||||
 | 
					    if ($allowNull !== null) return $allowNull;
 | 
				
			||||||
 | 
					    return $this->key !== null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected bool $allowEmpty;
 | 
					  protected ?bool $allowFalse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function isAllowFalse(): bool {
 | 
				
			||||||
 | 
					    $allowFalse = $this->allowFalse;
 | 
				
			||||||
 | 
					    if ($allowFalse !== null) return $allowFalse;
 | 
				
			||||||
 | 
					    return $this->key === null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function exists(): bool {
 | 
					  function exists(): bool {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $key = $this->key;
 | 
				
			||||||
    if ($key === null) return false;
 | 
					    if ($key === null) {
 | 
				
			||||||
    return cl::has($this->array, $key);
 | 
					      return $this->isAllowNull() || $this->dest !== null;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return cl::phas($this->dest, $key);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function available(): bool {
 | 
					  function available(): bool {
 | 
				
			||||||
    if (!$this->exists()) return false;
 | 
					    if (!$this->exists()) return false;
 | 
				
			||||||
    $value = cl::get($this->array, $this->key);
 | 
					    $key = $this->key;
 | 
				
			||||||
    if ($value === null) return $this->allowNull;
 | 
					    if ($key === null) $value = $this->dest;
 | 
				
			||||||
    if ($value === false) return $this->allowFalse;
 | 
					    else $value = cl::pget($this->dest, $key);
 | 
				
			||||||
    if ($value === "") return $this->allowEmpty;
 | 
					    if ($value === "") return $this->allowEmpty;
 | 
				
			||||||
 | 
					    if ($value === null) return $this->isAllowNull();
 | 
				
			||||||
 | 
					    if ($value === false) return $this->isAllowFalse();
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get($default=null) {
 | 
					  function get($default=null) {
 | 
				
			||||||
    if ($this->key === null) return $default;
 | 
					    $key = $this->key;
 | 
				
			||||||
    $value = cl::get($this->array, $this->key, $default);
 | 
					    if ($key === null) $value = $this->dest;
 | 
				
			||||||
    if ($value === null && !$this->allowNull) return $default;
 | 
					    else $value = cl::pget($this->dest, $key, $default);
 | 
				
			||||||
    if ($value === false && !$this->allowFalse) return $default;
 | 
					 | 
				
			||||||
    if ($value === "" && !$this->allowEmpty) return $default;
 | 
					    if ($value === "" && !$this->allowEmpty) return $default;
 | 
				
			||||||
 | 
					    if ($value === null && !$this->isAllowNull()) return $default;
 | 
				
			||||||
 | 
					    if ($value === false && !$this->isAllowFalse()) return $default;
 | 
				
			||||||
    return $value;
 | 
					    return $value;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function set($value): void {
 | 
					  function set($value): void {
 | 
				
			||||||
    if ($this->key === null) return;
 | 
					    $key = $this->key;
 | 
				
			||||||
    cl::set($this->array, $this->key, $value);
 | 
					    if ($key === null) {
 | 
				
			||||||
 | 
					      if (!$this->protectDest) $this->dest = $value;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      cl::pset($this->dest, $key, $value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function del(): void {
 | 
					  function del(): void {
 | 
				
			||||||
    if ($this->key === null) return;
 | 
					    $key = $this->key;
 | 
				
			||||||
    cl::del($this->array, $this->key);
 | 
					    if ($key === null) {
 | 
				
			||||||
 | 
					      if (!$this->protectDest) $this->dest = null;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      cl::pdel($this->dest, $key);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addKey($key): self {
 | 
				
			||||||
 | 
					    if ($key === null) return $this;
 | 
				
			||||||
 | 
					    if ($this->key !== null) $key = cl::merge($this->key, $key);
 | 
				
			||||||
 | 
					    return new KeyAccess($this->dest, $key, [
 | 
				
			||||||
 | 
					      "allow_empty" => $this->allowEmpty,
 | 
				
			||||||
 | 
					      "allow_null" => $this->allowNull,
 | 
				
			||||||
 | 
					      "allow_false" => $this->allowFalse,
 | 
				
			||||||
 | 
					      "protect_dest" => $this->protectDest,
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureAssoc(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $dest =& $this->dest;
 | 
				
			||||||
 | 
					    $prefix = $params["key_prefix"] ?? null;
 | 
				
			||||||
 | 
					    $suffix = $params["key_suffix"] ?? null;
 | 
				
			||||||
 | 
					    $index = 0;
 | 
				
			||||||
 | 
					    foreach ($keys as $key) {
 | 
				
			||||||
 | 
					      if ($prefix !== null || $suffix !== null) {
 | 
				
			||||||
 | 
					        $destKey = "$prefix$key$suffix";
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        # préserver les clés numériques
 | 
				
			||||||
 | 
					        $destKey = $key;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if ($dest !== null && array_key_exists($destKey, $dest)) continue;
 | 
				
			||||||
 | 
					      while (in_array($index, $keys, true)) {
 | 
				
			||||||
 | 
					        $index++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if ($dest !== null && array_key_exists($index, $dest)) {
 | 
				
			||||||
 | 
					        $dest[$destKey] = $dest[$index];
 | 
				
			||||||
 | 
					        unset($dest[$index]);
 | 
				
			||||||
 | 
					        $index++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $dest =& $this->dest;
 | 
				
			||||||
 | 
					    $keys = array_keys($defaults);
 | 
				
			||||||
 | 
					    $prefix = $params["key_prefix"] ?? null;
 | 
				
			||||||
 | 
					    $suffix = $params["key_suffix"] ?? null;
 | 
				
			||||||
 | 
					    foreach ($keys as $key) {
 | 
				
			||||||
 | 
					      $destKey = "$prefix$key$suffix";
 | 
				
			||||||
 | 
					      $haveMissing = $missings !== null && array_key_exists($key, $missings);
 | 
				
			||||||
 | 
					      if ($dest === null || !array_key_exists($destKey, $dest)) {
 | 
				
			||||||
 | 
					        $dest[$destKey] = $defaults[$key];
 | 
				
			||||||
 | 
					      } elseif ($haveMissing && $dest[$destKey] === $missings[$key]) {
 | 
				
			||||||
 | 
					        $dest[$destKey] = $defaults[$key];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function deleteMissings(array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $dest =& $this->dest;
 | 
				
			||||||
 | 
					    $prefix = $params["key_prefix"] ?? null;
 | 
				
			||||||
 | 
					    $suffix = $params["key_suffix"] ?? null;
 | 
				
			||||||
 | 
					    foreach ($missings as $key => $missing) {
 | 
				
			||||||
 | 
					      $destKey = "$prefix$key$suffix";
 | 
				
			||||||
 | 
					      if (array_key_exists($destKey, $dest) && $dest[$destKey] === $missing) {
 | 
				
			||||||
 | 
					        unset($dest[$destKey]);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureOrder(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $dest =& $this->dest;
 | 
				
			||||||
 | 
					    if ($dest === null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $prefix = $params["key_prefix"] ?? null;
 | 
				
			||||||
 | 
					    $suffix = $params["key_suffix"] ?? null;
 | 
				
			||||||
 | 
					    if ($prefix !== null || $suffix !== null) {
 | 
				
			||||||
 | 
					      foreach ($keys as &$key) {
 | 
				
			||||||
 | 
					        $key = "$prefix$key$suffix";
 | 
				
			||||||
 | 
					      }; unset($key);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $destKeys = array_keys($dest);
 | 
				
			||||||
 | 
					    $keyCount = count($keys);
 | 
				
			||||||
 | 
					    if (array_slice($destKeys, 0, $keyCount) === $keys) {
 | 
				
			||||||
 | 
					      # si le tableau a déjà les bonnes clés dans le bon ordre, rien à faire
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ordered = [];
 | 
				
			||||||
 | 
					    foreach ($keys as $key) {
 | 
				
			||||||
 | 
					      if (array_key_exists($key, $dest)) {
 | 
				
			||||||
 | 
					        $ordered[$key] = $dest[$key];
 | 
				
			||||||
 | 
					        unset($dest[$key]);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $preserveKeys = $params["preserve_keys"] ?? false;
 | 
				
			||||||
 | 
					    if ($preserveKeys) $dest = cl::merge2($ordered, $dest);
 | 
				
			||||||
 | 
					    else $dest = array_merge($ordered, $dest);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,49 +1,27 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					 | 
				
			||||||
use nulib\cl;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class PostAccess: accès à une valeur de $_POST
 | 
					 * Class PostAccess: accès à une valeur de $_POST
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class PostAccess extends FormAccess {
 | 
					class PostAccess extends FormAccess {
 | 
				
			||||||
  function exists(): bool {
 | 
					  function exists(): bool {
 | 
				
			||||||
    $key = $this->key;
 | 
					    return $this->_exists($_POST);
 | 
				
			||||||
    if ($key === null) return false;
 | 
					 | 
				
			||||||
    return array_key_exists($key, $_POST);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function available(): bool {
 | 
					  public function available(): bool {
 | 
				
			||||||
    $key = $this->key;
 | 
					    return $this->_available($_POST);
 | 
				
			||||||
    if ($key === null) return false;
 | 
					 | 
				
			||||||
    if (array_key_exists($key, $_POST)) {
 | 
					 | 
				
			||||||
      return $this->allowEmpty || $_POST[$key] !== "";
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get($default=null) {
 | 
					  function get($default=null) {
 | 
				
			||||||
    $key = $this->key;
 | 
					    return $this->_get($default, $_POST);
 | 
				
			||||||
    if ($key === null) return $default;
 | 
					 | 
				
			||||||
    if (array_key_exists($key, $_POST)) {
 | 
					 | 
				
			||||||
      $value = $_POST[$key];
 | 
					 | 
				
			||||||
      if ($value === "" && !$this->allowEmpty) return $default;
 | 
					 | 
				
			||||||
      return $value;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return $default;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function set($value): void {
 | 
					  function set($value): void {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $this->_set($value, $_POST);
 | 
				
			||||||
    if ($key === null) return;
 | 
					 | 
				
			||||||
    cl::set($_POST, $key, $value);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function del(): void {
 | 
					  function del(): void {
 | 
				
			||||||
    $key = $this->key;
 | 
					    $this->_del($_POST);
 | 
				
			||||||
    if ($key === null) return;
 | 
					 | 
				
			||||||
    cl::del($_POST, $key);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										173
									
								
								src/php/access/PropertyAccess.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/php/access/PropertyAccess.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,173 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\StateException;
 | 
				
			||||||
 | 
					use nulib\str;
 | 
				
			||||||
 | 
					use ReflectionClass;
 | 
				
			||||||
 | 
					use ReflectionException;
 | 
				
			||||||
 | 
					use ReflectionProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PropertyAccess extends AbstractAccess {
 | 
				
			||||||
 | 
					  const PROTECT_DEST = true;
 | 
				
			||||||
 | 
					  const MAP_NAMES = true;
 | 
				
			||||||
 | 
					  const ALLOW_NULL = true;
 | 
				
			||||||
 | 
					  const ALLOW_FALSE = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function __construct(?object $dest, ?string $name=null, ?array $params=null) {
 | 
				
			||||||
 | 
					    parent::__construct($params);
 | 
				
			||||||
 | 
					    $this->protectDest = $params["protect_dest"] ?? static::PROTECT_DEST;
 | 
				
			||||||
 | 
					    $this->mapNames = $params["map_names"] ?? static::MAP_NAMES;
 | 
				
			||||||
 | 
					    $this->_setName($name);
 | 
				
			||||||
 | 
					    $this->_setDest($dest);
 | 
				
			||||||
 | 
					    $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL;
 | 
				
			||||||
 | 
					    $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected bool $protectDest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected ?object $dest;
 | 
				
			||||||
 | 
					  protected bool $mapNames;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected ?string $name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected ?ReflectionProperty $property;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function _getName(string $key): string {
 | 
				
			||||||
 | 
					    return $this->mapNames? str::us2camel($key): $key;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  private function _setName(?string $name): void {
 | 
				
			||||||
 | 
					    if ($name !== null) $name = $this->_getName($name);
 | 
				
			||||||
 | 
					    $this->name = $name;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function _getProperty(?string $name, ?ReflectionClass $class, ?object $object=null): ?ReflectionProperty {
 | 
				
			||||||
 | 
					    $property = null;
 | 
				
			||||||
 | 
					    if ($class === null && $object !== null) {
 | 
				
			||||||
 | 
					      $class = new ReflectionClass($object);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($class !== null && $name !== null) {
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        $property = $class->getProperty($name);
 | 
				
			||||||
 | 
					        $property->setAccessible(true);
 | 
				
			||||||
 | 
					      } catch (ReflectionException $e) {
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $property;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function _setDest(?object $dest): void {
 | 
				
			||||||
 | 
					    $this->dest = $dest;
 | 
				
			||||||
 | 
					    $this->property = $this->_getProperty($this->name, null, $dest);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function reset(?object $dest, ?string $name=null): self {
 | 
				
			||||||
 | 
					    $this->_setName($name);
 | 
				
			||||||
 | 
					    $this->_setDest($dest);
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function resetKey($name=null): self {
 | 
				
			||||||
 | 
					    $this->_setName($name);
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected bool $allowNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected bool $allowFalse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function exists(): bool {
 | 
				
			||||||
 | 
					    $name = $this->name;
 | 
				
			||||||
 | 
					    if ($this->dest === null) return false;
 | 
				
			||||||
 | 
					    return $name === null
 | 
				
			||||||
 | 
					      || $this->property !== null
 | 
				
			||||||
 | 
					      || property_exists($this->dest, $name);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _get($default=null) {
 | 
				
			||||||
 | 
					    $name = $this->name;
 | 
				
			||||||
 | 
					    $property = $this->property;
 | 
				
			||||||
 | 
					    if ($this->dest === null) {
 | 
				
			||||||
 | 
					      return $default;
 | 
				
			||||||
 | 
					    } elseif ($name === null) {
 | 
				
			||||||
 | 
					      return $this->dest;
 | 
				
			||||||
 | 
					    } elseif ($property !== null) {
 | 
				
			||||||
 | 
					      return $property->getValue($this->dest);
 | 
				
			||||||
 | 
					    } elseif (property_exists($this->dest, $name)) {
 | 
				
			||||||
 | 
					      return $this->dest->$name;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return $default;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function available(): bool {
 | 
				
			||||||
 | 
					    if (!$this->exists()) return false;
 | 
				
			||||||
 | 
					    $value = $this->_get();
 | 
				
			||||||
 | 
					    if ($value === "") return $this->allowEmpty;
 | 
				
			||||||
 | 
					    if ($value === null) return $this->allowNull;
 | 
				
			||||||
 | 
					    if ($value === false) return $this->allowFalse;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function get($default=null) {
 | 
				
			||||||
 | 
					    if (!$this->exists()) return $default;
 | 
				
			||||||
 | 
					    $value = $this->_get();
 | 
				
			||||||
 | 
					    if ($value === "" && !$this->allowEmpty) return $default;
 | 
				
			||||||
 | 
					    if ($value === null && !$this->allowNull) return $default;
 | 
				
			||||||
 | 
					    if ($value === false && !$this->allowFalse) return $default;
 | 
				
			||||||
 | 
					    return $value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _set($value): void {
 | 
				
			||||||
 | 
					    $name = $this->name;
 | 
				
			||||||
 | 
					    $property = $this->property;
 | 
				
			||||||
 | 
					    if ($this->dest === null) {
 | 
				
			||||||
 | 
					      throw StateException::unexpected_state("dest is null");
 | 
				
			||||||
 | 
					    } elseif ($name === null) {
 | 
				
			||||||
 | 
					      if (!$this->protectDest) $this->_setDest($value);
 | 
				
			||||||
 | 
					    } elseif ($property !== null) {
 | 
				
			||||||
 | 
					      $property->setValue($this->dest, $value);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $this->dest->$name = $value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function set($value): void {
 | 
				
			||||||
 | 
					    $this->_set($value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function del(): void {
 | 
				
			||||||
 | 
					    $this->_set(null);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addKey($key): IAccess {
 | 
				
			||||||
 | 
					    if ($key === null) return $this;
 | 
				
			||||||
 | 
					    return new ChainAccess($this, $key);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $dest = $this->dest;
 | 
				
			||||||
 | 
					    if ($dest === null) {
 | 
				
			||||||
 | 
					      # comme ne connait pas la classe de l'objet destination, on n'essaie pas
 | 
				
			||||||
 | 
					      # de le créer
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $class = new ReflectionClass($dest);
 | 
				
			||||||
 | 
					    $keys = array_keys($defaults);
 | 
				
			||||||
 | 
					    $prefix = $params["key_prefix"] ?? null;
 | 
				
			||||||
 | 
					    $suffix = $params["key_suffix"] ?? null;
 | 
				
			||||||
 | 
					    foreach ($keys as $key) {
 | 
				
			||||||
 | 
					      $name = $this->_getName("$prefix$key$suffix");
 | 
				
			||||||
 | 
					      $property = $this->_getProperty($name, $class);
 | 
				
			||||||
 | 
					      if ($property !== null) {
 | 
				
			||||||
 | 
					        $type = $property->getType();
 | 
				
			||||||
 | 
					        if ($type !== null && !$property->isInitialized($dest) && $type->allowsNull()) {
 | 
				
			||||||
 | 
					          # initialiser avec null au lieu de $defaults[$key] pour respecter le
 | 
				
			||||||
 | 
					          # type de la propriété
 | 
				
			||||||
 | 
					          $property->setValue($dest, null);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } elseif (!property_exists($dest, $name)) {
 | 
				
			||||||
 | 
					        $dest->$name = $defaults[$key];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class ShadowAccess: accès en lecture depuis une instance de {@link IAccess}
 | 
					 * Class ShadowAccess: accès en lecture depuis une instance de {@link IAccess}
 | 
				
			||||||
@ -16,6 +16,7 @@ namespace nur\sery\wip\php\access;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
class ShadowAccess extends AbstractAccess {
 | 
					class ShadowAccess extends AbstractAccess {
 | 
				
			||||||
  function __construct(IAccess $reader, IAccess $writer) {
 | 
					  function __construct(IAccess $reader, IAccess $writer) {
 | 
				
			||||||
 | 
					    parent::__construct();
 | 
				
			||||||
    $this->reader = $reader;
 | 
					    $this->reader = $reader;
 | 
				
			||||||
    $this->writer = $writer;
 | 
					    $this->writer = $writer;
 | 
				
			||||||
    $this->getter = $reader;
 | 
					    $this->getter = $reader;
 | 
				
			||||||
@ -27,6 +28,10 @@ class ShadowAccess extends AbstractAccess {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  protected IGetter $getter;
 | 
					  protected IGetter $getter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function isAllowEmpty(): bool {
 | 
				
			||||||
 | 
					    return $this->getter->isAllowEmpty();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function exists(): bool {
 | 
					  function exists(): bool {
 | 
				
			||||||
    return $this->getter->exists();
 | 
					    return $this->getter->exists();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -48,4 +53,20 @@ class ShadowAccess extends AbstractAccess {
 | 
				
			|||||||
    $this->writer->del();
 | 
					    $this->writer->del();
 | 
				
			||||||
    $this->getter = $this->reader;
 | 
					    $this->getter = $this->reader;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addKey($key): IAccess {
 | 
				
			||||||
 | 
					    return new ChainAccess($this, $key);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureAssoc(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $this->writer->ensureAssoc($keys, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $this->writer->ensureKeys($defaults, $missings, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureOrder(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $this->writer->ensureOrder($keys, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,56 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\access;
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					class ValueAccess extends KeyAccess {
 | 
				
			||||||
 * Class ValueAccess: accès à une valeur unitaire
 | 
					  const ALLOW_NULL = false;
 | 
				
			||||||
 */
 | 
					  const ALLOW_FALSE = true;
 | 
				
			||||||
class ValueAccess extends AbstractAccess {
 | 
					  const PROTECT_DEST = false;
 | 
				
			||||||
  function __construct(&$value, ?array $params=null) {
 | 
					 | 
				
			||||||
    $this->value =& $value;
 | 
					 | 
				
			||||||
    $this->allowNull = $params["allow_null"] ?? false;
 | 
					 | 
				
			||||||
    $this->allowFalse = $params["allow_false"] ?? true;
 | 
					 | 
				
			||||||
    $this->allowEmpty = $params["allow_empty"] ?? true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var mixed */
 | 
					 | 
				
			||||||
  protected $value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function reset(&$value): self {
 | 
					 | 
				
			||||||
    $this->value =& $value;
 | 
					 | 
				
			||||||
    return $this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected bool $allowNull;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected bool $allowFalse;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected bool $allowEmpty;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function exists(): bool {
 | 
					 | 
				
			||||||
    return $this->allowNull || $this->value !== null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function available(): bool {
 | 
					 | 
				
			||||||
    if (!$this->exists()) return false;
 | 
					 | 
				
			||||||
    $value = $this->value;
 | 
					 | 
				
			||||||
    if ($value === false) return $this->allowFalse;
 | 
					 | 
				
			||||||
    if ($value === "") return $this->allowEmpty;
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function get($default=null) {
 | 
					 | 
				
			||||||
    $value = $this->value;
 | 
					 | 
				
			||||||
    if ($value === null && !$this->allowNull) return $default;
 | 
					 | 
				
			||||||
    if ($value === false && !$this->allowFalse) return $default;
 | 
					 | 
				
			||||||
    if ($value === "" && !$this->allowEmpty) return $default;
 | 
					 | 
				
			||||||
    return $value;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function set($value): void {
 | 
					 | 
				
			||||||
    $this->value = $value;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function del(): void {
 | 
					 | 
				
			||||||
    $this->value = null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\coll;
 | 
					namespace nulib\php\coll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Iterator;
 | 
					use Iterator;
 | 
				
			||||||
use IteratorAggregate;
 | 
					use IteratorAggregate;
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
use nulib\php\func;
 | 
					use nulib\php\func;
 | 
				
			||||||
use nur\sery\wip\php\iter;
 | 
					use nulib\php\iter;
 | 
				
			||||||
use Traversable;
 | 
					use Traversable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,10 @@
 | 
				
			|||||||
<?php # -*- coding: utf-8 mode: php -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8
 | 
					<?php # -*- coding: utf-8 mode: php -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8
 | 
				
			||||||
namespace nur\sery\wip\php;
 | 
					namespace nulib\php;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Exception;
 | 
					use Exception;
 | 
				
			||||||
use Generator;
 | 
					use Generator;
 | 
				
			||||||
use Iterator;
 | 
					use Iterator;
 | 
				
			||||||
use IteratorAggregate;
 | 
					use IteratorAggregate;
 | 
				
			||||||
use nulib\php\ICloseable;
 | 
					 | 
				
			||||||
use nulib\StopException;
 | 
					use nulib\StopException;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use Traversable;
 | 
					use Traversable;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										67
									
								
								src/schema/ConsolidatedResult.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/schema/ConsolidatedResult.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\ref\schema\ref_analyze;
 | 
				
			||||||
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ConsolidatedResult extends Result {
 | 
				
			||||||
 | 
					  protected int $highestResult;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function reset(): void {
 | 
				
			||||||
 | 
					    parent::reset();
 | 
				
			||||||
 | 
					    $this->highestResult = -1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _addMessage(Wrapper $wrapper, $prefix=null): void {
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult();
 | 
				
			||||||
 | 
					    $message = $this->message;
 | 
				
			||||||
 | 
					    if ($message) $message .= "\n";
 | 
				
			||||||
 | 
					    if ($prefix !== null) $message .= "$prefix: ";
 | 
				
			||||||
 | 
					    $message .= $result->message;
 | 
				
			||||||
 | 
					    $this->message = $message;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addMissingMessage(Wrapper $wrapper, $prefix=null): void {
 | 
				
			||||||
 | 
					    if ($this->highestResult < ref_analyze::MISSING) {
 | 
				
			||||||
 | 
					      $this->present = false;
 | 
				
			||||||
 | 
					      $this->available = false;
 | 
				
			||||||
 | 
					      $this->null = false;
 | 
				
			||||||
 | 
					      $this->valid = false;
 | 
				
			||||||
 | 
					      $this->messageKey = "missing";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $this->_addMessage($wrapper, $prefix);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addUnavailableMessage(Wrapper $wrapper, $prefix=null): void {
 | 
				
			||||||
 | 
					    if ($this->highestResult < ref_analyze::UNAVAILABLE) {
 | 
				
			||||||
 | 
					      $this->present = true;
 | 
				
			||||||
 | 
					      $this->available = false;
 | 
				
			||||||
 | 
					      $this->null = false;
 | 
				
			||||||
 | 
					      $this->valid = false;
 | 
				
			||||||
 | 
					      $this->messageKey = "unavailable";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $this->_addMessage($wrapper, $prefix);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addNullMessage(Wrapper $wrapper, $prefix=null): void {
 | 
				
			||||||
 | 
					    if ($this->highestResult < ref_analyze::NULL) {
 | 
				
			||||||
 | 
					      $this->present = true;
 | 
				
			||||||
 | 
					      $this->available = true;
 | 
				
			||||||
 | 
					      $this->null = true;
 | 
				
			||||||
 | 
					      $this->valid = false;
 | 
				
			||||||
 | 
					      $this->messageKey = "null";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $this->_addMessage($wrapper, $prefix);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addInvalidMessage(Wrapper $wrapper, $prefix=null): void {
 | 
				
			||||||
 | 
					    if ($this->highestResult < ref_analyze::INVALID) {
 | 
				
			||||||
 | 
					      $this->present = true;
 | 
				
			||||||
 | 
					      $this->available = true;
 | 
				
			||||||
 | 
					      $this->null = false;
 | 
				
			||||||
 | 
					      $this->valid = false;
 | 
				
			||||||
 | 
					      $this->messageKey = "invalid";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $this->_addMessage($wrapper, $prefix);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema;
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OldSchema {
 | 
					class OldSchema {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,11 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema;
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use IteratorAggregate;
 | 
					use nulib\cl;
 | 
				
			||||||
use nur\sery\wip\schema\_assoc\AssocResult;
 | 
					use nulib\ref\schema\ref_analyze;
 | 
				
			||||||
use nur\sery\wip\schema\_list\ListResult;
 | 
					use nulib\ref\schema\ref_schema;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					use Throwable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class Result: résultat de l'analyse ou de la normalisation d'une valeur
 | 
					 * Class Result: résultat de l'analyse ou de la normalisation d'une valeur
 | 
				
			||||||
@ -17,48 +18,140 @@ use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
				
			|||||||
 * @property bool $normalized si la valeur est valide, est-elle normalisée?
 | 
					 * @property bool $normalized si la valeur est valide, est-elle normalisée?
 | 
				
			||||||
 * @property string|null $messageKey clé de message si la valeur n'est pas valide
 | 
					 * @property string|null $messageKey clé de message si la valeur n'est pas valide
 | 
				
			||||||
 * @property string|null $message message si la valeur n'est pas valide
 | 
					 * @property string|null $message message si la valeur n'est pas valide
 | 
				
			||||||
 | 
					 * @property Throwable|null $exception l'exception qui a fait échouer la
 | 
				
			||||||
 | 
					 * validation le cas échéant
 | 
				
			||||||
 * @property string|null $origValue valeur originale avant extraction et analyse
 | 
					 * @property string|null $origValue valeur originale avant extraction et analyse
 | 
				
			||||||
 * @property mixed|null $normalizedValue la valeur normalisée si elle est
 | 
					 * @property mixed|null $normalizedValue la valeur normalisée si elle est
 | 
				
			||||||
 *  disponible, null sinon. ce champ est utilisé comme optimisation si la valeur
 | 
					 *  disponible, null sinon. ce champ est utilisé comme optimisation si la valeur
 | 
				
			||||||
 *  normalisée a déjà été calculée
 | 
					 *  normalisée a déjà été calculée
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
abstract class Result implements IteratorAggregate {
 | 
					class Result {
 | 
				
			||||||
  const KEYS = [
 | 
					 | 
				
			||||||
    "resultAvailable",
 | 
					 | 
				
			||||||
    "present", "available", "null", "valid", "normalized",
 | 
					 | 
				
			||||||
    "messageKey", "message",
 | 
					 | 
				
			||||||
    "origValue", "normalizedValue",
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function __construct() {
 | 
					  function __construct() {
 | 
				
			||||||
    $this->reset();
 | 
					    $this->reset();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAssoc(?AssocResult &$result=null): bool { return false; }
 | 
					  public bool $resultAvailable;
 | 
				
			||||||
  function isList(?ListResult &$result=null): bool { return false; }
 | 
					  public bool $present;
 | 
				
			||||||
  function isScalar(?ScalarResult &$result=null): bool { return false; }
 | 
					  public bool $available;
 | 
				
			||||||
 | 
					  public bool $null;
 | 
				
			||||||
  /**
 | 
					  public bool $valid;
 | 
				
			||||||
   * Obtenir la liste des clés valides pour les valeurs accessibles via cet
 | 
					  public bool $normalized;
 | 
				
			||||||
   * objet
 | 
					  public ?string $messageKey;
 | 
				
			||||||
   */
 | 
					  public ?string $message;
 | 
				
			||||||
  abstract function getKeys(): array;
 | 
					  public ?Throwable $exception;
 | 
				
			||||||
 | 
					  public $origValue;
 | 
				
			||||||
  /**
 | 
					  public $normalizedValue;
 | 
				
			||||||
   * sélectionner le résultat associé à la clé spécifiée
 | 
					 | 
				
			||||||
   *
 | 
					 | 
				
			||||||
   * @param string|int|null $key
 | 
					 | 
				
			||||||
   * @return Result $this
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  abstract function select($key): Result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getIterator() {
 | 
					 | 
				
			||||||
    foreach ($this->getKeys() as $key) {
 | 
					 | 
				
			||||||
      yield $key => $this->select($key);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $this->select(null);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** réinitialiser tous les objets résultats accessibles via cet objet */
 | 
					  /** réinitialiser tous les objets résultats accessibles via cet objet */
 | 
				
			||||||
  abstract function reset(): void;
 | 
					  function reset(): void {
 | 
				
			||||||
 | 
					    $this->resultAvailable = false;
 | 
				
			||||||
 | 
					    $this->present = false;
 | 
				
			||||||
 | 
					    $this->available = false;
 | 
				
			||||||
 | 
					    $this->null = false;
 | 
				
			||||||
 | 
					    $this->valid = false;
 | 
				
			||||||
 | 
					    $this->normalized = false;
 | 
				
			||||||
 | 
					    $this->messageKey = null;
 | 
				
			||||||
 | 
					    $this->message = null;
 | 
				
			||||||
 | 
					    $this->exception = null;
 | 
				
			||||||
 | 
					    $this->origValue = null;
 | 
				
			||||||
 | 
					    $this->normalizedValue = null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function getMessage(string $key,  Schema $schema): string {
 | 
				
			||||||
 | 
					    $message = cl::get($schema->messages, $key);
 | 
				
			||||||
 | 
					    if ($message !== null) return $message;
 | 
				
			||||||
 | 
					    return cl::get(ref_schema::MESSAGES, $key);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setMissing( Schema $schema): int {
 | 
				
			||||||
 | 
					    $this->resultAvailable = true;
 | 
				
			||||||
 | 
					    $this->present = false;
 | 
				
			||||||
 | 
					    $this->available = false;
 | 
				
			||||||
 | 
					    if (!$schema->required) {
 | 
				
			||||||
 | 
					      $this->null = false;
 | 
				
			||||||
 | 
					      $this->valid = true;
 | 
				
			||||||
 | 
					      $this->normalized = true;
 | 
				
			||||||
 | 
					      return ref_analyze::NORMALIZED;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $this->messageKey = $messageKey = "missing";
 | 
				
			||||||
 | 
					      $this->message = $this->getMessage($messageKey, $schema);
 | 
				
			||||||
 | 
					      return ref_analyze::MISSING;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setUnavailable( Schema $schema): int {
 | 
				
			||||||
 | 
					    $this->resultAvailable = true;
 | 
				
			||||||
 | 
					    $this->present = true;
 | 
				
			||||||
 | 
					    $this->available = false;
 | 
				
			||||||
 | 
					    if (!$schema->required) {
 | 
				
			||||||
 | 
					      $this->null = false;
 | 
				
			||||||
 | 
					      $this->valid = true;
 | 
				
			||||||
 | 
					      $this->normalized = true;
 | 
				
			||||||
 | 
					      return ref_analyze::NORMALIZED;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $this->messageKey = $messageKey = "unavailable";
 | 
				
			||||||
 | 
					      $this->message = $this->getMessage($messageKey, $schema);
 | 
				
			||||||
 | 
					      return ref_analyze::UNAVAILABLE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setNull( Schema $schema): int {
 | 
				
			||||||
 | 
					    $this->resultAvailable = true;
 | 
				
			||||||
 | 
					    $this->present = true;
 | 
				
			||||||
 | 
					    $this->available = true;
 | 
				
			||||||
 | 
					    $this->null = true;
 | 
				
			||||||
 | 
					    if ($schema->nullable) {
 | 
				
			||||||
 | 
					      $this->valid = true;
 | 
				
			||||||
 | 
					      $this->normalized = true;
 | 
				
			||||||
 | 
					      return ref_analyze::NORMALIZED;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $this->messageKey = $messageKey = "null";
 | 
				
			||||||
 | 
					      $this->message = $this->getMessage($messageKey, $schema);
 | 
				
			||||||
 | 
					      return ref_analyze::NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setInvalid($value,  Schema $schema, ?Throwable $exception=null): int {
 | 
				
			||||||
 | 
					    $this->resultAvailable = true;
 | 
				
			||||||
 | 
					    $this->present = true;
 | 
				
			||||||
 | 
					    $this->available = true;
 | 
				
			||||||
 | 
					    $this->null = false;
 | 
				
			||||||
 | 
					    $this->valid = false;
 | 
				
			||||||
 | 
					    $this->origValue = $value;
 | 
				
			||||||
 | 
					    $this->messageKey = $messageKey = "invalid";
 | 
				
			||||||
 | 
					    $message = null;
 | 
				
			||||||
 | 
					    if ($exception !== null) $message = ValueException::get_message($exception);
 | 
				
			||||||
 | 
					    if (!$message) $message = $this->getMessage($messageKey, $schema);
 | 
				
			||||||
 | 
					    $this->message = $message;
 | 
				
			||||||
 | 
					    $this->exception = $exception;
 | 
				
			||||||
 | 
					    return ref_analyze::INVALID;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setValid($normalizedValue=null): int {
 | 
				
			||||||
 | 
					    $this->resultAvailable = true;
 | 
				
			||||||
 | 
					    $this->present = true;
 | 
				
			||||||
 | 
					    $this->available = true;
 | 
				
			||||||
 | 
					    $this->null = false;
 | 
				
			||||||
 | 
					    $this->valid = true;
 | 
				
			||||||
 | 
					    $this->normalizedValue = $normalizedValue;
 | 
				
			||||||
 | 
					    return ref_analyze::VALID;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function setNormalized(): int {
 | 
				
			||||||
 | 
					    $this->resultAvailable = true;
 | 
				
			||||||
 | 
					    $this->present = true;
 | 
				
			||||||
 | 
					    $this->available = true;
 | 
				
			||||||
 | 
					    $this->null = false;
 | 
				
			||||||
 | 
					    $this->valid = true;
 | 
				
			||||||
 | 
					    $this->normalized = true;
 | 
				
			||||||
 | 
					    return ref_analyze::NORMALIZED;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function throw(bool $throw): void {
 | 
				
			||||||
 | 
					    if ($throw) {
 | 
				
			||||||
 | 
					      $exception = $this->exception;
 | 
				
			||||||
 | 
					      if ($exception !== null) throw $exception;
 | 
				
			||||||
 | 
					      else throw new ValueException($this->message);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,22 +1,45 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema;
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use ArrayAccess;
 | 
					use ArrayAccess;
 | 
				
			||||||
use nulib\AccessException;
 | 
					use nulib\AccessException;
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
use nulib\ref\schema\ref_schema;
 | 
					use nulib\ref\schema\ref_schema;
 | 
				
			||||||
use nulib\ref\schema\ref_types;
 | 
					use nulib\ref\schema\ref_types;
 | 
				
			||||||
use nur\sery\wip\schema\_assoc\AssocSchema;
 | 
					use nulib\schema\_assoc\AssocSchema;
 | 
				
			||||||
use nur\sery\wip\schema\_list\ListSchema;
 | 
					use nulib\schema\_list\ListSchema;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
use nur\sery\wip\schema\types\IType;
 | 
					use nulib\schema\types\IType;
 | 
				
			||||||
use nur\sery\wip\schema\types\tarray;
 | 
					use nulib\schema\types\tarray;
 | 
				
			||||||
use nur\sery\wip\schema\types\tbool;
 | 
					use nulib\schema\types\tbool;
 | 
				
			||||||
use nur\sery\wip\schema\types\tcallable;
 | 
					use nulib\schema\types\tcontent;
 | 
				
			||||||
use nur\sery\wip\schema\types\tcontent;
 | 
					use nulib\schema\types\tfunc;
 | 
				
			||||||
use nur\sery\wip\schema\types\tpkey;
 | 
					use nulib\schema\types\tpkey;
 | 
				
			||||||
use nur\sery\wip\schema\types\trawstring;
 | 
					use nulib\schema\types\trawstring;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class Schema
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @property-read array|IType $type
 | 
				
			||||||
 | 
					 * @property-read mixed $default
 | 
				
			||||||
 | 
					 * @property-read string|null $title
 | 
				
			||||||
 | 
					 * @property-read bool $required
 | 
				
			||||||
 | 
					 * @property-read bool $nullable
 | 
				
			||||||
 | 
					 * @property-read string|array|null $desc
 | 
				
			||||||
 | 
					 * @property-read callable|null $analyzerFunc
 | 
				
			||||||
 | 
					 * @property-read callable|null $extractorFunc
 | 
				
			||||||
 | 
					 * @property-read callable|null $parserFunc
 | 
				
			||||||
 | 
					 * @property-read callable|null $normalizerFunc
 | 
				
			||||||
 | 
					 * @property-read array|null $messages
 | 
				
			||||||
 | 
					 * @property-read callable|null $formatterFunc
 | 
				
			||||||
 | 
					 * @property-read mixed $format
 | 
				
			||||||
 | 
					 * @property-read array $nature
 | 
				
			||||||
 | 
					 * @property-read array|null $schema
 | 
				
			||||||
 | 
					 * @property-read string|int|null $name
 | 
				
			||||||
 | 
					 * @property-read string|array|null $pkey
 | 
				
			||||||
 | 
					 * @property-read string|null $header
 | 
				
			||||||
 | 
					 * @property-read bool|null $computed
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
abstract class Schema implements ArrayAccess {
 | 
					abstract class Schema implements ArrayAccess {
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * créer le cas échéant une nouvelle instance de {@link Schema} à partir d'une
 | 
					   * créer le cas échéant une nouvelle instance de {@link Schema} à partir d'une
 | 
				
			||||||
@ -27,7 +50,7 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
   * l'instance de Schema nouvelle créée
 | 
					   * l'instance de Schema nouvelle créée
 | 
				
			||||||
   * - sinon, prendre $definition comme définition
 | 
					   * - sinon, prendre $definition comme définition
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  static function ns(&$schema, $definition=null, $definitionKey=null, bool $normalize=true): self {
 | 
					  static function ns($definition=null, $definitionKey=null, &$schema=null, bool $normalize=true): self {
 | 
				
			||||||
    if (is_array($schema)) {
 | 
					    if (is_array($schema)) {
 | 
				
			||||||
      $definition = $schema;
 | 
					      $definition = $schema;
 | 
				
			||||||
      $schema = null;
 | 
					      $schema = null;
 | 
				
			||||||
@ -51,13 +74,13 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
   * variable $value (si $valueKey===null) ou $value[$valueKey] si $valueKey
 | 
					   * variable $value (si $valueKey===null) ou $value[$valueKey] si $valueKey
 | 
				
			||||||
   * n'est pas null
 | 
					   * n'est pas null
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  static function nw(&$value=null, $valueKey=null, &$schema=null, $definition=null, ?Wrapper &$wrapper=null): Wrapper {
 | 
					  static function nw(&$value=null, $valueKey=null, $definition=null, &$schema=null, ?Wrapper &$wrapper=null): Wrapper {
 | 
				
			||||||
    if ($definition === null) {
 | 
					    if ($definition === null) {
 | 
				
			||||||
      # bien que techniquement, $definition peut être null (il s'agit alors du
 | 
					      # bien que techniquement, $definition peut être null (il s'agit alors du
 | 
				
			||||||
      # schéma d'un scalaire quelconque), on ne l'autorise pas ici
 | 
					      # schéma d'un scalaire quelconque), on ne l'autorise pas ici
 | 
				
			||||||
      throw SchemaException::invalid_schema("definition is required");
 | 
					      throw SchemaException::invalid_schema("definition is required");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return self::ns($schema, $definition)->getWrapper($value, $valueKey, $wrapper);
 | 
					    return self::ns($definition, null, $schema)->getWrapper($value, $valueKey, null, $wrapper);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected static function have_nature(array $definition, ?string &$nature=null): bool {
 | 
					  protected static function have_nature(array $definition, ?string &$nature=null): bool {
 | 
				
			||||||
@ -75,18 +98,18 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected static function _normalize(&$definition, $definitionKey=null): void {
 | 
					  protected static function _normalize_definition(&$definition, $definitionKey=null, ?array $natureMetaschema=null): void {
 | 
				
			||||||
    if (!is_array($definition)) $definition = [$definition];
 | 
					    if (!is_array($definition)) $definition = [$definition];
 | 
				
			||||||
    # s'assurer que toutes les clés existent avec leur valeur par défaut
 | 
					    # s'assurer que toutes les clés existent avec leur valeur par défaut
 | 
				
			||||||
    $index = 0;
 | 
					    $index = 0;
 | 
				
			||||||
    foreach (array_keys(ref_schema::SCALAR_METASCHEMA) as $key) {
 | 
					    foreach (array_keys(ref_schema::VALUE_METASCHEMA) as $key) {
 | 
				
			||||||
      if (!array_key_exists($key, $definition)) {
 | 
					      if (!array_key_exists($key, $definition)) {
 | 
				
			||||||
        if (array_key_exists($index, $definition)) {
 | 
					        if (array_key_exists($index, $definition)) {
 | 
				
			||||||
          $definition[$key] = $definition[$index];
 | 
					          $definition[$key] = $definition[$index];
 | 
				
			||||||
          unset($definition[$index]);
 | 
					          unset($definition[$index]);
 | 
				
			||||||
          $index++;
 | 
					          $index++;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          $definition[$key] = ref_schema::SCALAR_METASCHEMA[$key][1];
 | 
					          $definition[$key] = ref_schema::VALUE_METASCHEMA[$key][1];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -138,6 +161,12 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
    # nature
 | 
					    # nature
 | 
				
			||||||
    $nature = $definition[""];
 | 
					    $nature = $definition[""];
 | 
				
			||||||
    tarray::ensure_array($nature);
 | 
					    tarray::ensure_array($nature);
 | 
				
			||||||
 | 
					    $natureMetaschema ??= ref_schema::NATURE_METASCHEMA;
 | 
				
			||||||
 | 
					    foreach (array_keys($natureMetaschema) as $key) {
 | 
				
			||||||
 | 
					      if (!array_key_exists($key, $nature)) {
 | 
				
			||||||
 | 
					        $nature[$key] = $natureMetaschema[$key][1];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    $definition[""] = $nature;
 | 
					    $definition[""] = $nature;
 | 
				
			||||||
    # name, pkey, header
 | 
					    # name, pkey, header
 | 
				
			||||||
    $name = $definition["name"];
 | 
					    $name = $definition["name"];
 | 
				
			||||||
@ -158,22 +187,22 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
    tbool::ensure_bool($definition["required"]);
 | 
					    tbool::ensure_bool($definition["required"]);
 | 
				
			||||||
    tbool::ensure_bool($definition["nullable"]);
 | 
					    tbool::ensure_bool($definition["nullable"]);
 | 
				
			||||||
    tcontent::ensure_ncontent($definition["desc"]);
 | 
					    tcontent::ensure_ncontent($definition["desc"]);
 | 
				
			||||||
    tcallable::ensure_ncallable($definition["analyzer_func"]);
 | 
					    tfunc::ensure_nfunc($definition["analyzer_func"]);
 | 
				
			||||||
    tcallable::ensure_ncallable($definition["extractor_func"]);
 | 
					    tfunc::ensure_nfunc($definition["extractor_func"]);
 | 
				
			||||||
    tcallable::ensure_ncallable($definition["parser_func"]);
 | 
					    tfunc::ensure_nfunc($definition["parser_func"]);
 | 
				
			||||||
    tcallable::ensure_ncallable($definition["normalizer_func"]);
 | 
					    tfunc::ensure_nfunc($definition["normalizer_func"]);
 | 
				
			||||||
    tarray::ensure_narray($definition["messages"]);
 | 
					    tarray::ensure_narray($definition["messages"]);
 | 
				
			||||||
    tcallable::ensure_ncallable($definition["formatter_func"]);
 | 
					    tfunc::ensure_nfunc($definition["formatter_func"]);
 | 
				
			||||||
    tbool::ensure_nbool($definition["computed"]);
 | 
					    tbool::ensure_nbool($definition["computed"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch ($nature[0] ?? null) {
 | 
					    switch ($nature[0] ?? null) {
 | 
				
			||||||
    case "assoc":
 | 
					    case "assoc":
 | 
				
			||||||
      foreach ($definition["schema"] as $key => &$keydef) {
 | 
					      foreach ($definition["schema"] as $key => &$keydef) {
 | 
				
			||||||
        self::_normalize($keydef, $key);
 | 
					        self::_normalize_definition($keydef, $key);
 | 
				
			||||||
      }; unset($keydef);
 | 
					      }; unset($keydef);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case "list":
 | 
					    case "list":
 | 
				
			||||||
      self::_normalize($definition["schema"]);
 | 
					      self::_normalize_definition($definition["schema"]);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -223,11 +252,11 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
    case "assoc":
 | 
					    case "assoc":
 | 
				
			||||||
      foreach ($definition["schema"] as &$keydef) {
 | 
					      foreach ($definition["schema"] as &$keydef) {
 | 
				
			||||||
        self::_ensure_schema_instances($keydef);
 | 
					        self::_ensure_schema_instances($keydef);
 | 
				
			||||||
        Schema::ns($keydef, null, null, false);
 | 
					        Schema::ns(null, null, $keydef, false);
 | 
				
			||||||
      }; unset($keydef);
 | 
					      }; unset($keydef);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case "list":
 | 
					    case "list":
 | 
				
			||||||
      Schema::ns($definition["schema"], null, null, false);
 | 
					      Schema::ns(null, null, $definition["schema"], false);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -246,14 +275,16 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
    return $this->_definition;
 | 
					    return $this->_definition;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** retourner true si le schéma est de nature tableau associatif */
 | 
					  /**
 | 
				
			||||||
  function isAssoc(?AssocSchema &$schema=null): bool { return false; }
 | 
					   * retourner la liste des clés valides pour l'accès aux valeurs et résultats
 | 
				
			||||||
  /** retourner true si le schéma est de nature liste */
 | 
					   */
 | 
				
			||||||
  function isList(?ListSchema &$schema=null): bool { return false; }
 | 
					  abstract function getKeys(): array;
 | 
				
			||||||
  /** retourner true si le schéma est de nature scalaire */
 | 
					 | 
				
			||||||
  function isScalar(?ScalarSchema &$schema=null): bool { return false; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  abstract function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): Wrapper;
 | 
					  abstract function getSchema($key=false): Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  abstract protected function newWrapper(): Wrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  abstract function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): Wrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #############################################################################
 | 
					  #############################################################################
 | 
				
			||||||
  # key & properties
 | 
					  # key & properties
 | 
				
			||||||
@ -272,7 +303,15 @@ abstract class Schema implements ArrayAccess {
 | 
				
			|||||||
    throw AccessException::read_only(null, $offset);
 | 
					    throw AccessException::read_only(null, $offset);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const _PROPERTY_PKEYS = [];
 | 
					  const _PROPERTY_PKEYS = [
 | 
				
			||||||
 | 
					    "analyzerFunc" => "analyzer_func",
 | 
				
			||||||
 | 
					    "extractorFunc" => "extractor_func",
 | 
				
			||||||
 | 
					    "parserFunc" => "parser_func",
 | 
				
			||||||
 | 
					    "normalizerFunc" => "normalizer_func",
 | 
				
			||||||
 | 
					    "formatterFunc" => "formatter_func",
 | 
				
			||||||
 | 
					    "nature" => ["", 0],
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function __get($name) {
 | 
					  function __get($name) {
 | 
				
			||||||
    $pkey = cl::get(static::_PROPERTY_PKEYS, $name, $name);
 | 
					    $pkey = cl::get(static::_PROPERTY_PKEYS, $name, $name);
 | 
				
			||||||
    return cl::pget($this->definition, $pkey);
 | 
					    return cl::pget($this->definition, $pkey);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema;
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Exception;
 | 
					use Exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,20 +1,29 @@
 | 
				
			|||||||
# nulib\schema
 | 
					# nulib\schema
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* instance de WrapperContext directement dans le schéma 
 | 
					* rajouter l'attribut "size" pour spécifier la taille maximale des valeurs
 | 
				
			||||||
* plus de {key} ni {orig} dans messages
 | 
					  * cela pourrait servir pour générer automatiquement des tables SQL
 | 
				
			||||||
  * les messages standard ne sont utilisés que s'il n'y a pas de message dans
 | 
					  * ou pour modéliser un schéma FSV
 | 
				
			||||||
    l'exception
 | 
					
 | 
				
			||||||
  * si instance de UserException, prendre le message "non technique" pour
 | 
					* support allowed_values
 | 
				
			||||||
    résultat
 | 
					
 | 
				
			||||||
* valeurs composite/computed
 | 
					* valeurs composite/computed
 | 
				
			||||||
  * analyse / vérification de la valeur complète après calcul du résultat, si
 | 
					  * analyse / vérification de la valeur complète après calcul du résultat, si
 | 
				
			||||||
    tous les résultats sont bons
 | 
					    tous les résultats sont bons
 | 
				
			||||||
  * calcul des valeurs composites/computed par une fonction avant/après l'analyse
 | 
					  * calcul des valeurs composites/computed par une fonction avant/après l'analyse
 | 
				
			||||||
    globale si résultat ok
 | 
					    globale si résultat ok
 | 
				
			||||||
 | 
					  * fonction getter_func, setter_func, deleter_func pour les propriétés de type
 | 
				
			||||||
 | 
					    computed
 | 
				
			||||||
* tdate et tdatetime. qu'en est-il des autres classes (delay, etc.)
 | 
					* tdate et tdatetime. qu'en est-il des autres classes (delay, etc.)
 | 
				
			||||||
  * possibilité de spécifier le format de la date à analyser 
 | 
					  * parse_format pour spécifier le format d'analyse au lieu de l'auto-détecter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* ScalarSchema::from_property()
 | 
					* ScalarSchema::from_property()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* l'argument $format de AssocWrapper::format() est un tableau associatif
 | 
				
			||||||
 | 
					  `[$key => $format]`
 | 
				
			||||||
 | 
					  cela permet de spécifier des format spécifiques pour certains champs.
 | 
				
			||||||
 | 
					  * cela signifie que la valeur de retour n'est pas string :-(
 | 
				
			||||||
 | 
					    retourner string|array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe
 | 
					* dans AssocSchema, support `[key_prefix]` qui permet de spécifier un préfixe
 | 
				
			||||||
  commun aux champs dans le tableau destination, e.g
 | 
					  commun aux champs dans le tableau destination, e.g
 | 
				
			||||||
  ~~~php
 | 
					  ~~~php
 | 
				
			||||||
@ -58,6 +67,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  la définition de ces "circonstances" est encore à faire: soit un paramètre
 | 
					  la définition de ces "circonstances" est encore à faire: soit un paramètre
 | 
				
			||||||
  lors de la définition du schéma, soit un truc magique du genre "toutes les
 | 
					  lors de la définition du schéma, soit un truc magique du genre "toutes les
 | 
				
			||||||
  valeurs séquentielles sont des clés du schéma"
 | 
					  valeurs séquentielles sont des clés du schéma", soit un mode automatique
 | 
				
			||||||
 | 
					  activé par un paramètre où une valeur "val" devient "val"=>true si la clé
 | 
				
			||||||
 | 
					  "val" existe dans le schéma
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
 | 
					-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
 | 
				
			||||||
@ -1,20 +1,105 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema;
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use ArrayAccess;
 | 
					use ArrayAccess;
 | 
				
			||||||
use IteratorAggregate;
 | 
					use IteratorAggregate;
 | 
				
			||||||
use nur\sery\wip\schema\_assoc\AssocWrapper;
 | 
					use nulib\php\func;
 | 
				
			||||||
use nur\sery\wip\schema\_list\ListWrapper;
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarWrapper;
 | 
					use nulib\schema\types\IType;
 | 
				
			||||||
use nur\sery\wip\schema\types\IType;
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class Wrapper implements ArrayAccess, IteratorAggregate {
 | 
					abstract class Wrapper implements ArrayAccess, IteratorAggregate {
 | 
				
			||||||
  function isAssoc(?AssocWrapper &$wrapper=null): bool { return false; }
 | 
					  protected WrapperContext $context;
 | 
				
			||||||
  function isList(?ListWrapper &$wrapper=null): bool { return false; }
 | 
					 | 
				
			||||||
  function isScalar(?ScalarWrapper &$wrapper=null): bool { return false; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** spécifier la valeur destination gérée par cet objet */
 | 
					  /** changer les paramètres de gestion des valeurs */
 | 
				
			||||||
  abstract function reset(&$value, $valueKey=null, ?bool $verifix=null): self;
 | 
					  function resetParams(?array $params): void {
 | 
				
			||||||
 | 
					    $this->context->resetParams($params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function resetContext(bool $resetSelectedKey): void {
 | 
				
			||||||
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    $type = $context->schema->type;
 | 
				
			||||||
 | 
					    if (is_array($type)) $type = $type[0];
 | 
				
			||||||
 | 
					    if (is_string($type)) $type = types::get($context->schema->nullable, $type);
 | 
				
			||||||
 | 
					    $context->type = $type;
 | 
				
			||||||
 | 
					    $context->result->reset();
 | 
				
			||||||
 | 
					    $context->analyzed = false;
 | 
				
			||||||
 | 
					    $context->normalized = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function afterModify(?array $params, bool $resetSelectedKey=false): void {
 | 
				
			||||||
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    $this->resetContext($resetSelectedKey);
 | 
				
			||||||
 | 
					    if ($params["analyze"] ?? $context->analyze) {
 | 
				
			||||||
 | 
					      $this->analyze($params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($context->analyzed && ($params["normalize"] ?? $context->normalize)) {
 | 
				
			||||||
 | 
					      $this->normalize($params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function newInput(&$value): Input {
 | 
				
			||||||
 | 
					    return new Input($value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * spécifier la valeur destination gérée par cet objet.
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param ?array $params paramètres spécifique à cet appel, qui peuvent être
 | 
				
			||||||
 | 
					   * différent des paramètres par défaut
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function reset(&$value, $valueKey=null, ?array $params=null): Wrapper {
 | 
				
			||||||
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    if ($value instanceof Input) $input = $value;
 | 
				
			||||||
 | 
					    else $input = $this->newInput($value);
 | 
				
			||||||
 | 
					    $context->input = $input;
 | 
				
			||||||
 | 
					    $context->valueKey = $valueKey;
 | 
				
			||||||
 | 
					    $this->afterModify($params, true);
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** analyser la valeur */
 | 
				
			||||||
 | 
					  abstract static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function analyze(?array $params=null): bool {
 | 
				
			||||||
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    $reanalyze = $params["reanalyze"] ?? false;
 | 
				
			||||||
 | 
					    if ($context->analyzed && !$reanalyze) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static::_analyze($context, $this, $params);
 | 
				
			||||||
 | 
					    $context->analyzed = true;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** normaliser la valeur */
 | 
				
			||||||
 | 
					  abstract static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function getConsolidatedResult(): Result {
 | 
				
			||||||
 | 
					    return $this->context->result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function normalize(?array $params=null): bool {
 | 
				
			||||||
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // il faut que la valeur soit analysée avant de la normaliser
 | 
				
			||||||
 | 
					    static::analyze($params);
 | 
				
			||||||
 | 
					    if (!$context->analyzed) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $renormalize = $params["renormalize"] ?? false;
 | 
				
			||||||
 | 
					    if ($renormalize || !$context->normalized) {
 | 
				
			||||||
 | 
					      $modified = static::_normalize($context, $this, $params);
 | 
				
			||||||
 | 
					      $context->normalized = true;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $modified = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $result = $this->getConsolidatedResult();
 | 
				
			||||||
 | 
					    if (!$result->valid) {
 | 
				
			||||||
 | 
					      $result->throw($params["throw"] ?? $context->throw);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $modified;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Obtenir la liste des clés valides pour les valeurs accessibles via cet
 | 
					   * Obtenir la liste des clés valides pour les valeurs accessibles via cet
 | 
				
			||||||
@ -25,50 +110,113 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate {
 | 
				
			|||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * sélectionner le wrapper associé à la clé spécifiée
 | 
					   * sélectionner le wrapper associé à la clé spécifiée
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
 | 
					   * $key peut valoir:
 | 
				
			||||||
 | 
					   * - false pour la clé courante (ne pas changer la sélection)
 | 
				
			||||||
 | 
					   * - null ou "" le wrapper de la valeur principale
 | 
				
			||||||
 | 
					   * - ou toute autre valeur présente dans {@link getKeys()} pour les valeurs
 | 
				
			||||||
 | 
					   * accessible via cet objet
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
   * @param string|int|null $key
 | 
					   * @param string|int|null $key
 | 
				
			||||||
   * @return Wrapper $this
 | 
					   * @return Wrapper $this
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  abstract function select($key): Wrapper;
 | 
					  abstract function select($key=null): Wrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getIterator() {
 | 
					  function getIterator() {
 | 
				
			||||||
    foreach ($this->getKeys() as $key) {
 | 
					    foreach ($this->getKeys() as $key) {
 | 
				
			||||||
      yield $key => $this->select($key);
 | 
					      yield $key => $this->select($key);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $this->select(null);
 | 
					    $this->select();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * obtenir le résultat de l'appel d'une des fonctions {@link set()} ou
 | 
					   * obtenir le résultat de l'analyse de la valeur du wrapper sélectionné
 | 
				
			||||||
   * {@link unset()}
 | 
					   *
 | 
				
			||||||
 | 
					   * cette fonction doit être appelée après {@link set()} ou {@link unset()} et
 | 
				
			||||||
 | 
					   * après que le wrapper aie été sélectionné avec {@link select()}
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * $key peut valoir:
 | 
				
			||||||
 | 
					   * - false pour la clé sélectionnée avec {@link select()}
 | 
				
			||||||
 | 
					   * - null pour le résultat consolidé
 | 
				
			||||||
 | 
					   * - "" pour le résultat de l'analyse de la valeur principale
 | 
				
			||||||
 | 
					   * - ou toute autre valeur présente dans {@link getKeys()} pour le résultat
 | 
				
			||||||
 | 
					   * de l'analyse des valeurs correspondantes
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  abstract function getResult(): Result;
 | 
					  function getResult($key=false): Result {
 | 
				
			||||||
 | 
					    if ($key === false || $key === "") return $this->context->result;
 | 
				
			||||||
 | 
					    if ($key === null) return $this->getConsolidatedResult();
 | 
				
			||||||
 | 
					    throw ValueException::invalid_key($key);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** retourner true si la valeur existe */
 | 
					  /** retourner true si la valeur existe */
 | 
				
			||||||
  abstract function isPresent(): bool;
 | 
					  function isPresent($key=false): bool {
 | 
				
			||||||
 | 
					    return $this->getResult($key)->present;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** retourner le type associé à la valeur */
 | 
					  /** retourner le type associé à la valeur */
 | 
				
			||||||
  abstract function getType(): IType;
 | 
					  function getType($key=false): IType {
 | 
				
			||||||
 | 
					    return $this->context->type;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** retourner true si la valeur est disponible */
 | 
					  /** retourner true si la valeur est disponible */
 | 
				
			||||||
  abstract function isAvailable(): bool;
 | 
					  function isAvailable($key=false): bool {
 | 
				
			||||||
 | 
					    return $this->getResult($key)->available;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** retourner true si la valeur est nulle */
 | 
				
			||||||
 | 
					  function isNull($key=false): bool {
 | 
				
			||||||
 | 
					    return $this->getResult($key)->null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** retourner true si la valeur est valide */
 | 
					  /** retourner true si la valeur est valide */
 | 
				
			||||||
  abstract function isValid(): bool;
 | 
					  function isValid($key=false): bool {
 | 
				
			||||||
 | 
					    return $this->getResult($key)->valid;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** retourner true si la valeur est dans sa forme normalisée */
 | 
					  /** retourner true si la valeur est dans sa forme normalisée */
 | 
				
			||||||
  abstract function isNormalized(): bool;
 | 
					  function isNormalized($key=false): bool {
 | 
				
			||||||
 | 
					    return $this->getResult($key)->normalized;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** obtenir la valeur */
 | 
					  function get($default=null, $key=false) {
 | 
				
			||||||
  abstract function get($default=null);
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    if (!$context->result->available) return $default;
 | 
				
			||||||
 | 
					    return $context->input->get($context->valueKey);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** remplacer la valeur */
 | 
					  function set($value, ?array $params=null, $key=false): self {
 | 
				
			||||||
  abstract function set($value): self;
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    $context->input->set($value, $context->valueKey);
 | 
				
			||||||
 | 
					    $this->afterModify($params);
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** supprimer la valeur */
 | 
					  function unset(?array $params=null, $key=false): self {
 | 
				
			||||||
  abstract function unset(): self;
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    $context->input->unset($context->valueKey);
 | 
				
			||||||
 | 
					    $this->afterModify($params);
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function _format(WrapperContext $context, $format=null): string {
 | 
				
			||||||
 | 
					    $value = $context->input->get($context->valueKey);
 | 
				
			||||||
 | 
					    /** @var func $formatterFunc */
 | 
				
			||||||
 | 
					    $formatterFunc = $context->schema->formatterFunc;
 | 
				
			||||||
 | 
					    if ($formatterFunc !== null) {
 | 
				
			||||||
 | 
					      # la fonction formatter n'a pas forcément accès au format de la définition
 | 
				
			||||||
 | 
					      # le lui fournir ici
 | 
				
			||||||
 | 
					      $format ??= $context->schema->format;
 | 
				
			||||||
 | 
					      return $formatterFunc->invoke([$value, $format, $context, $this]);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      # on assume que le type a été initialisé avec le format de la définition
 | 
				
			||||||
 | 
					      # le cas échéant
 | 
				
			||||||
 | 
					      return $context->type->format($value, $format);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** formatter la valeur pour affichage */
 | 
					  /** formatter la valeur pour affichage */
 | 
				
			||||||
  abstract function format($format=null): string;
 | 
					  function format($format=null, $key=false): string {
 | 
				
			||||||
 | 
					    return $this->_format($this->context, $format);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #############################################################################
 | 
					  #############################################################################
 | 
				
			||||||
  # key & properties
 | 
					  # key & properties
 | 
				
			||||||
@ -78,14 +226,14 @@ abstract class Wrapper implements ArrayAccess, IteratorAggregate {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function offsetGet($offset) {
 | 
					  function offsetGet($offset) {
 | 
				
			||||||
    return $this->select($offset);
 | 
					    return $this->get(null, $offset);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function offsetSet($offset, $value): void {
 | 
					  function offsetSet($offset, $value): void {
 | 
				
			||||||
    $this->select($offset)->set($value);
 | 
					    $this->set($value, null, $offset);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function offsetUnset($offset): void {
 | 
					  function offsetUnset($offset): void {
 | 
				
			||||||
    $this->select($offset)->unset();
 | 
					    $this->unset(null, $offset);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,30 +1,44 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema;
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					use nulib\ref\schema\ref_schema;
 | 
				
			||||||
use nur\sery\wip\schema\types\IType;
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
 | 
					use nulib\schema\types\IType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WrapperContext {
 | 
					class WrapperContext {
 | 
				
			||||||
  function __construct(Schema $schema, Wrapper $wrapper, Input $input, $valueKey, Result $result) {
 | 
					
 | 
				
			||||||
 | 
					  function __construct(Schema $schema, ?Input $input, $valueKey, ?array $params) {
 | 
				
			||||||
 | 
					    $this->resetParams($params);
 | 
				
			||||||
    $this->schema = $schema;
 | 
					    $this->schema = $schema;
 | 
				
			||||||
    $this->wrapper = $wrapper;
 | 
					    if ($input !== null) $this->input = $input;
 | 
				
			||||||
    $this->input = $input;
 | 
					 | 
				
			||||||
    $this->result = $result;
 | 
					 | 
				
			||||||
    $this->type = null;
 | 
					 | 
				
			||||||
    $this->origValue = null;
 | 
					 | 
				
			||||||
    $this->value = null;
 | 
					 | 
				
			||||||
    $this->valueKey = $valueKey;
 | 
					    $this->valueKey = $valueKey;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public ?array $params;
 | 
				
			||||||
 | 
					  public bool $analyze, $analyzed = false;
 | 
				
			||||||
 | 
					  public bool $normalize, $normalized = false;
 | 
				
			||||||
 | 
					  public ?bool $throw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function resetParams(?array $params): void {
 | 
				
			||||||
 | 
					    $this->params = $params;
 | 
				
			||||||
 | 
					    $this->analyze = $params["analyze"] ?? ref_schema::PARAMS_SCHEMA["analyze"][1];
 | 
				
			||||||
 | 
					    $this->normalize = $params["normalize"] ?? ref_schema::PARAMS_SCHEMA["normalize"][1];
 | 
				
			||||||
 | 
					    $this->throw = $params["throw"] ?? ref_schema::PARAMS_SCHEMA["throw"][1];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** schéma de la valeur */
 | 
				
			||||||
  public Schema $schema;
 | 
					  public Schema $schema;
 | 
				
			||||||
  public Wrapper $wrapper;
 | 
					  /** source et destination de la valeur */
 | 
				
			||||||
  public Input $input;
 | 
					  public Input $input;
 | 
				
			||||||
  public Result $result;
 | 
					  /** @var string|int|null clé de la valeur dans le tableau destination */
 | 
				
			||||||
  public ?IType $type;
 | 
					 | 
				
			||||||
  /** @var mixed */
 | 
					 | 
				
			||||||
  public $origValue;
 | 
					 | 
				
			||||||
  /** @var mixed */
 | 
					 | 
				
			||||||
  public $value;
 | 
					 | 
				
			||||||
  /** @var int|string|null */
 | 
					 | 
				
			||||||
  public $valueKey;
 | 
					  public $valueKey;
 | 
				
			||||||
 | 
					  /** @var mixed */
 | 
				
			||||||
 | 
					  public $origValue = null;
 | 
				
			||||||
 | 
					  /** @var mixed */
 | 
				
			||||||
 | 
					  public $value = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** type de la valeur de la clé sélectionnée après analyse */
 | 
				
			||||||
 | 
					  public ?IType $type = null;
 | 
				
			||||||
 | 
					  /** résultat de l'analyse de la valeur de la clé sélectionnée */
 | 
				
			||||||
 | 
					  public ?Result $result = null;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,53 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nur\sery\wip\schema\_assoc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nulib\ValueException;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AssocResult extends Result {
 | 
					 | 
				
			||||||
  function __construct(Result $arrayResult, array &$keyResults) {
 | 
					 | 
				
			||||||
    $this->arrayResult = $arrayResult;
 | 
					 | 
				
			||||||
    $this->keyResults =& $keyResults;
 | 
					 | 
				
			||||||
    $this->result =& $this->arrayResult;
 | 
					 | 
				
			||||||
    parent::__construct();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function isAssoc(?AssocResult &$result=null): bool { $result = $this; return true;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected Result $arrayResult;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var Result[] */
 | 
					 | 
				
			||||||
  protected array $keyResults;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getKeys(): array {
 | 
					 | 
				
			||||||
    return array_keys($this->keyResults);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected Result $result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function select($key): Result {
 | 
					 | 
				
			||||||
    if ($key === null) {
 | 
					 | 
				
			||||||
      $this->result =& $this->arrayResult;
 | 
					 | 
				
			||||||
    } elseif (array_key_exists($key, $this->keyResults)) {
 | 
					 | 
				
			||||||
      $this->result =& $this->keyResults[$key];
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      throw ValueException::invalid_key($key);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return $this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function reset(): void {
 | 
					 | 
				
			||||||
    $this->arrayResult->reset();
 | 
					 | 
				
			||||||
    foreach ($this->keyResults as $result) {
 | 
					 | 
				
			||||||
      $result->reset();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function __get(string $name) {
 | 
					 | 
				
			||||||
    return $this->result[$name];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function __set(string $name, $value): void {
 | 
					 | 
				
			||||||
    $this->result[$name] = $value;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,21 +1,19 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\_assoc;
 | 
					namespace nulib\schema\_assoc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
use nulib\ref\schema\ref_schema;
 | 
					use nulib\ref\schema\ref_schema;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\Wrapper;
 | 
					use nulib\schema\Wrapper;
 | 
				
			||||||
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class AssocSchema
 | 
					 * Class AssocSchema
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class AssocSchema extends Schema {
 | 
					class AssocSchema extends Schema {
 | 
				
			||||||
  /** @var array meta-schema d'un schéma de nature tableau associatif */
 | 
					 | 
				
			||||||
  const METASCHEMA = ref_schema::ASSOC_METASCHEMA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * indiquer si $definition est une définition de schéma de nature tableau
 | 
					   * indiquer si $definition est une définition de schéma de nature tableau
 | 
				
			||||||
   * associatif que {@link normalize()} pourrait normaliser
 | 
					   * associatif que {@link normalize_definition()} pourrait normaliser
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  static function isa_definition($definition): bool {
 | 
					  static function isa_definition($definition): bool {
 | 
				
			||||||
    if (!is_array($definition)) return false;
 | 
					    if (!is_array($definition)) return false;
 | 
				
			||||||
@ -27,7 +25,7 @@ class AssocSchema extends Schema {
 | 
				
			|||||||
    return !cl::have_num_keys($definition);
 | 
					    return !cl::have_num_keys($definition);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static function normalize($definition, $definitionKey=null): array {
 | 
					  static function normalize_definition($definition, $definitionKey=null): array {
 | 
				
			||||||
    if (!is_array($definition)) $definition = [$definition];
 | 
					    if (!is_array($definition)) $definition = [$definition];
 | 
				
			||||||
    if (!self::have_nature($definition)) {
 | 
					    if (!self::have_nature($definition)) {
 | 
				
			||||||
      $definition = [
 | 
					      $definition = [
 | 
				
			||||||
@ -36,7 +34,8 @@ class AssocSchema extends Schema {
 | 
				
			|||||||
        "schema" => $definition,
 | 
					        "schema" => $definition,
 | 
				
			||||||
      ];
 | 
					      ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    self::_normalize($definition, $definitionKey);
 | 
					    $natureMetaschema = array_merge(ref_schema::NATURE_METASCHEMA, ref_schema::ASSOC_NATURE_METASCHEMA);
 | 
				
			||||||
 | 
					    self::_normalize_definition($definition, $definitionKey, $natureMetaschema);
 | 
				
			||||||
    self::_ensure_nature($definition, "assoc", "array");
 | 
					    self::_ensure_nature($definition, "assoc", "array");
 | 
				
			||||||
    return $definition;
 | 
					    return $definition;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -44,25 +43,54 @@ class AssocSchema extends Schema {
 | 
				
			|||||||
  function __construct($definition=null, $definitionKey=null, bool $normalize=true) {
 | 
					  function __construct($definition=null, $definitionKey=null, bool $normalize=true) {
 | 
				
			||||||
    if ($definition === null) $definition = static::SCHEMA;
 | 
					    if ($definition === null) $definition = static::SCHEMA;
 | 
				
			||||||
    if ($normalize) {
 | 
					    if ($normalize) {
 | 
				
			||||||
      $definition = self::normalize($definition, $definitionKey);
 | 
					      $definition = self::normalize_definition($definition, $definitionKey);
 | 
				
			||||||
      $this->_definition = $definition;
 | 
					      $this->_definition = $definition;
 | 
				
			||||||
      self::_ensure_type($definition);
 | 
					      self::_ensure_type($definition);
 | 
				
			||||||
      self::_ensure_schema_instances($definition);
 | 
					      self::_ensure_schema_instances($definition);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      # ici, $definition contient un schema déjà instancié, mais c'est le mieux
 | 
				
			||||||
 | 
					      # qu'on puisse faire
 | 
				
			||||||
 | 
					      $this->_definition = $definition;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $this->definition = $definition;
 | 
					    $this->definition = $definition;
 | 
				
			||||||
 | 
					    $keys = [];
 | 
				
			||||||
 | 
					    foreach ($definition["schema"] as $key => $schema) {
 | 
				
			||||||
 | 
					      if (!$schema["computed"]) $keys[] = $key;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $this->keys = $keys;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAssoc(?AssocSchema &$schema=null): bool {
 | 
					  protected array $keys;
 | 
				
			||||||
    $schema = $this;
 | 
					
 | 
				
			||||||
    return true;
 | 
					  function getKeys(): array {
 | 
				
			||||||
 | 
					    return $this->keys;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getSchema($key=false): Schema {
 | 
				
			||||||
 | 
					    if ($key === null || $key === false) return $this;
 | 
				
			||||||
 | 
					    $schema = $this->definition["schema"][$key] ?? null;
 | 
				
			||||||
 | 
					    if ($schema === null) throw ValueException::invalid_key($key);
 | 
				
			||||||
 | 
					    return $schema;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function newWrapper(): AssocWrapper {
 | 
					  protected function newWrapper(): AssocWrapper {
 | 
				
			||||||
    return new AssocWrapper($this);
 | 
					    return new AssocWrapper($this);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getWrapper(&$array=null, $arrayKey=null, ?Wrapper &$wrapper=null): AssocWrapper {
 | 
					  function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): AssocWrapper {
 | 
				
			||||||
 | 
					    # si pas de valeur ni de wrapper, pas d'analyse et donc pas d'exception
 | 
				
			||||||
 | 
					    # cf le code similaire dans AssocWrapper::__construct()
 | 
				
			||||||
 | 
					    $dontAnalyze = $value === null && $wrapper === null;
 | 
				
			||||||
    if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper();
 | 
					    if (!($wrapper instanceof AssocWrapper)) $wrapper = $this->newWrapper();
 | 
				
			||||||
    return $wrapper->reset($array, $arrayKey);
 | 
					
 | 
				
			||||||
 | 
					    # la nature du schéma peut contenir des paramètres par défaut
 | 
				
			||||||
 | 
					    $nature = $this->definition[""];
 | 
				
			||||||
 | 
					    foreach (array_keys(ref_schema::ASSOC_PARAMS_SCHEMA) as $paramKey) {
 | 
				
			||||||
 | 
					      $paramValue = $nature[$paramKey] ?? null;
 | 
				
			||||||
 | 
					      if ($paramValue !== null) $params[$paramKey] = $paramValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($params !== null) $wrapper->resetParams($params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $wrapper->reset($value, $valueKey, $dontAnalyze? ["analyze" => false]: null);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,140 +1,206 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\_assoc;
 | 
					namespace nulib\schema\_assoc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\cl;
 | 
				
			||||||
 | 
					use nulib\ref\schema\ref_analyze;
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarWrapper;
 | 
				
			||||||
 | 
					use nulib\schema\ConsolidatedResult;
 | 
				
			||||||
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\types\IType;
 | 
				
			||||||
 | 
					use nulib\schema\Wrapper;
 | 
				
			||||||
 | 
					use nulib\schema\WrapperContext;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarWrapper;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\IType;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Wrapper;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AssocWrapper extends Wrapper {
 | 
					class AssocWrapper extends Wrapper {
 | 
				
			||||||
  function __construct(AssocSchema $schema, &$array=null, $arrayKey=null, ?array $params=null) {
 | 
					  function __construct(AssocSchema $schema, &$value=null, $valueKey=null, ?array $params=null) {
 | 
				
			||||||
    $verifix = $params["verifix"] ?? true;
 | 
					    $this->context = $context = new AssocWrapperContext($schema, null, null, $params);
 | 
				
			||||||
    $throw = $params["throw"] ?? null;
 | 
					    $paramsNoThrow = cl::merge($params, [
 | 
				
			||||||
    if ($array !== null && $throw === null) {
 | 
					      "throw" => false,
 | 
				
			||||||
      # Si $value est null, ne pas lancer d'exception, parce qu'on considère que
 | 
					    ]);
 | 
				
			||||||
      # c'est une initialisation sans conséquences
 | 
					
 | 
				
			||||||
      $throw = true;
 | 
					    $keys = $schema->getKeys();
 | 
				
			||||||
 | 
					    $keyWrappers = [];
 | 
				
			||||||
 | 
					    foreach ($keys as $key) {
 | 
				
			||||||
 | 
					      $keyDummy = null;
 | 
				
			||||||
 | 
					      $keyWrappers[$key] = $schema->getSchema($key)->getWrapper($keyDummy, null, $paramsNoThrow);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $context->keys = $keys;
 | 
				
			||||||
 | 
					    $context->keyWrappers = $keyWrappers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $arrayDummy = null;
 | 
				
			||||||
 | 
					    $context->arrayWrapper = new ScalarWrapper($schema, $arrayDummy, null, $paramsNoThrow, $context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $context->consolidatedResult = new ConsolidatedResult();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($value !== null) {
 | 
				
			||||||
 | 
					      # n'initialiser que si $value n'est pas null
 | 
				
			||||||
 | 
					      $this->reset($value, $valueKey);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $this->schema = $schema;
 | 
					 | 
				
			||||||
    $this->verifix = $verifix;
 | 
					 | 
				
			||||||
    $this->throw = $throw ?? false;
 | 
					 | 
				
			||||||
    $this->result = new AssocResult();
 | 
					 | 
				
			||||||
    $this->reset($array, $arrayKey);
 | 
					 | 
				
			||||||
    $this->throw = $throw ?? true;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAssoc(?AssocWrapper &$wrapper=null): bool { $wrapper = $this; return true; }
 | 
					  /** @var AssocWrapperContext  */
 | 
				
			||||||
 | 
					  protected WrapperContext $context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected bool $verifix;
 | 
					  protected function resetContext(bool $resetSelectedKey): void {
 | 
				
			||||||
 | 
					    parent::resetContext($resetSelectedKey);
 | 
				
			||||||
  protected bool $throw;
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    $context->arrayWrapper->getResult()->reset();
 | 
				
			||||||
  /** schéma de ce tableau */
 | 
					    foreach ($context->keyWrappers as $wrapper) {
 | 
				
			||||||
  protected AssocSchema $schema;
 | 
					      $wrapper->getResult()->reset();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  /** source et destination de la valeur */
 | 
					    if ($resetSelectedKey) $context->selectedKey = null;
 | 
				
			||||||
  protected Input $input;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var string|int|null clé du tableau dans le tableau destination */
 | 
					 | 
				
			||||||
  protected $arrayKey;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected IType $arrayType;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected ScalarResult $arrayResult;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var IType[] */
 | 
					 | 
				
			||||||
  protected array $keyTypes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var Result[] */
 | 
					 | 
				
			||||||
  protected array $keyResults;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected AssocResult $result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected ?array $keys;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected ?array $wrappers;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected function newInput(&$value): Input {
 | 
					 | 
				
			||||||
    return new Input($value);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function reset(&$array, $arrayKey=null, ?bool $verifix=null): Wrapper {
 | 
					  function reset(&$value, $valueKey=null, ?array $params=null): Wrapper {
 | 
				
			||||||
    if ($array instanceof Input) $input = $array;
 | 
					    $context = $this->context;
 | 
				
			||||||
    else $input = $this->newInput($array);
 | 
					    if ($value instanceof Input) $input = $value;
 | 
				
			||||||
    $this->input = $input;
 | 
					    else $input = $this->newInput($value);
 | 
				
			||||||
    $this->arrayKey = $arrayKey;
 | 
					    $context->input = $input;
 | 
				
			||||||
    $this->analyze();
 | 
					    $context->valueKey = $valueKey;
 | 
				
			||||||
    if ($verifix ?? $this->verifix) $this->verifix();
 | 
					    foreach ($context->keyWrappers as $key => $keyWrapper) {
 | 
				
			||||||
 | 
					      $keyInput = $input->addKey($valueKey);
 | 
				
			||||||
 | 
					      $keyWrapper->reset($keyInput, $key, ["analyze" => false]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $this->afterModify($params, true);
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getKeys(): array {
 | 
					  function getKeys(): array {
 | 
				
			||||||
    return $this->keys;
 | 
					    return $this->context->keys;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function select($key=null): ScalarWrapper {
 | 
					  protected function _getWrapper($key): Wrapper {
 | 
				
			||||||
    $wrapper = $this->wrappers[$key] ?? null;
 | 
					    $context = $this->context;
 | 
				
			||||||
    if ($key !== null) return $wrapper;
 | 
					    if ($key === null || $key === "") return $context->arrayWrapper;
 | 
				
			||||||
    throw ValueException::invalid_key($key);
 | 
					    $wrapper = $context->keyWrappers[$key] ?? null;
 | 
				
			||||||
 | 
					    if ($wrapper === null) throw ValueException::invalid_key($key);
 | 
				
			||||||
 | 
					    return $wrapper;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @param Result[] $results */
 | 
					  /** @param string|int|null $key */
 | 
				
			||||||
  function verifix(?bool $throw=null, ?array &$results=null): bool {
 | 
					  function select($key=null): Wrapper {
 | 
				
			||||||
 | 
					    $wrapper = $this->_getWrapper($key);
 | 
				
			||||||
 | 
					    $this->context->selectedKey = $key;
 | 
				
			||||||
 | 
					    return $wrapper;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * @param AssocWrapperContext $context
 | 
				
			||||||
 | 
					   * @param AssocWrapper $wrapper
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int {
 | 
				
			||||||
 | 
					    if ($params["ensure_array"] ?? $context->ensureArray) {
 | 
				
			||||||
 | 
					      $valueKey = $context->valueKey;
 | 
				
			||||||
 | 
					      $array = $context->input->get($valueKey);
 | 
				
			||||||
 | 
					      if ($array === null) $context->input->set([], $valueKey);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getResult(): AssocResult {
 | 
					    if ($params["ensure_assoc"] ?? $context->ensureAssoc) {
 | 
				
			||||||
    return $this->result;
 | 
					      $context->input->ensureAssoc($context->schema->getKeys());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $what = ScalarWrapper::_analyze($context, $wrapper, $params);
 | 
				
			||||||
 | 
					    if (!$context->result->valid) return $what;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $result = $context->consolidatedResult;
 | 
				
			||||||
 | 
					    $result->setValid();
 | 
				
			||||||
 | 
					    foreach ($context->keyWrappers as $key => $keyWrapper) {
 | 
				
			||||||
 | 
					      $keyWrapper->analyze($params);
 | 
				
			||||||
 | 
					      if ($keyWrapper->isValid()) continue;
 | 
				
			||||||
 | 
					      $what = ref_analyze::INVALID;
 | 
				
			||||||
 | 
					      #XXX pour $prefix, utiliser si possible la description ou une autre valeur
 | 
				
			||||||
 | 
					      # "user-friendly". possibilité de sélectionner la valeur à utiliser avec
 | 
				
			||||||
 | 
					      # $params?
 | 
				
			||||||
 | 
					      $prefix = $key;
 | 
				
			||||||
 | 
					      if (!$keyWrapper->isPresent()) {
 | 
				
			||||||
 | 
					        $result->addMissingMessage($keyWrapper, $prefix);
 | 
				
			||||||
 | 
					      } elseif (!$keyWrapper->isAvailable()) {
 | 
				
			||||||
 | 
					        $result->addUnavailableMessage($keyWrapper, $prefix);
 | 
				
			||||||
 | 
					      } elseif ($keyWrapper->isNull()) {
 | 
				
			||||||
 | 
					        $result->addNullMessage($keyWrapper, $prefix);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        $result->addInvalidMessage($keyWrapper, $prefix);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $what;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isPresent(): bool {
 | 
					  /**
 | 
				
			||||||
    return $this->result->present;
 | 
					   * @param AssocWrapperContext $context
 | 
				
			||||||
 | 
					   * @param AssocWrapper $wrapper
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool {
 | 
				
			||||||
 | 
					    $schema = $context->schema;
 | 
				
			||||||
 | 
					    $keys = $schema->getKeys();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $defaults = [];
 | 
				
			||||||
 | 
					    $missings = null;
 | 
				
			||||||
 | 
					    foreach ($keys as $key) {
 | 
				
			||||||
 | 
					      $type = $wrapper->getType($key);
 | 
				
			||||||
 | 
					      $default = $schema->getSchema($key)->default;
 | 
				
			||||||
 | 
					      if ($default === null) $default = $type->getNullValue();
 | 
				
			||||||
 | 
					      $defaults[$key] = $default;
 | 
				
			||||||
 | 
					      $missing = $type->getMissingValue($valid);
 | 
				
			||||||
 | 
					      if ($valid) $missings[$key] = $missing;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($params["ensure_keys"] ?? $context->ensureKeys) {
 | 
				
			||||||
 | 
					      $context->input->ensureKeys($defaults, $missings, $params);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $context->input->deleteMissings($missings, $params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ($params["ensure_order"] ?? $context->ensureOrder) {
 | 
				
			||||||
 | 
					      $context->input->ensureOrder($keys, $params);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $modified = ScalarWrapper::_normalize($context, $wrapper, $params);
 | 
				
			||||||
 | 
					    foreach ($context->keyWrappers as $keyWrapper) {
 | 
				
			||||||
 | 
					      if ($keyWrapper->normalize($params)) $modified = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $modified;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getType(): IType {
 | 
					  protected function getConsolidatedResult(): Result {
 | 
				
			||||||
    return $this->arrayType;
 | 
					    return $this->context->consolidatedResult;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAvailable(): bool {
 | 
					  function getResult($key=false): Result {
 | 
				
			||||||
    return $this->result->available;
 | 
					    if ($key === null) return $this->getConsolidatedResult();
 | 
				
			||||||
 | 
					    if ($key === false) $key = $this->context->selectedKey;
 | 
				
			||||||
 | 
					    return $this->_getWrapper($key)->getResult();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid(): bool {
 | 
					  function getType($key=false): IType {
 | 
				
			||||||
    return $this->result->valid;
 | 
					    if ($key === false) $key = $this->context->selectedKey;
 | 
				
			||||||
 | 
					    return $this->_getWrapper($key)->getType();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isNormalized(): bool {
 | 
					  function get($default=null, $key=false) {
 | 
				
			||||||
    return $this->result->normalized;
 | 
					    $context = $this->context;
 | 
				
			||||||
 | 
					    if (!$context->arrayWrapper->isAvailable()) return $default;
 | 
				
			||||||
 | 
					    if ($key === false) $key = $context->selectedKey;
 | 
				
			||||||
 | 
					    return $this->_getWrapper($key)->get($default);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get($default=null) {
 | 
					  function set($value, ?array $params=null, $key=false): Wrapper {
 | 
				
			||||||
    if ($this->result->available) return $this->input->get($this->arrayKey);
 | 
					    $context = $this->context;
 | 
				
			||||||
    else return $default;
 | 
					    if ($key === false) $key = $context->selectedKey;
 | 
				
			||||||
  }
 | 
					    $this->_getWrapper($key)->set($value);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  function set($value, ?bool $verifix=null): AssocWrapper {
 | 
					 | 
				
			||||||
    $this->input->set($value, $this->arrayKey);
 | 
					 | 
				
			||||||
    $this->analyze();
 | 
					 | 
				
			||||||
    if ($verifix ?? $this->verifix) $this->verifix();
 | 
					 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function unset(?bool $verifix=null): AssocWrapper {
 | 
					  function unset(?array $params=null, $key=false): Wrapper {
 | 
				
			||||||
    $this->input->unset($this->arrayKey);
 | 
					    $context = $this->context;
 | 
				
			||||||
    $this->analyze();
 | 
					    if ($key === false) $key = $context->selectedKey;
 | 
				
			||||||
    if ($verifix ?? $this->verifix) $this->verifix();
 | 
					    $this->_getWrapper($key)->unset();
 | 
				
			||||||
    return $this;
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function format($format = null): string {
 | 
					  function format($format=null, $key=false): string {
 | 
				
			||||||
    // TODO: Implement format() method.
 | 
					    $context = $this->context;
 | 
				
			||||||
  }
 | 
					    if ($key === false) $key = $context->selectedKey;
 | 
				
			||||||
 | 
					    return $this->_getWrapper($key)->format($format);
 | 
				
			||||||
  function ensureKeys(): bool {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  function orderKeys(): bool {
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								src/schema/_assoc/AssocWrapperContext.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/schema/_assoc/AssocWrapperContext.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\schema\_assoc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\ref\schema\ref_schema;
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarWrapper;
 | 
				
			||||||
 | 
					use nulib\schema\ConsolidatedResult;
 | 
				
			||||||
 | 
					use nulib\schema\Wrapper;
 | 
				
			||||||
 | 
					use nulib\schema\WrapperContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AssocWrapperContext extends WrapperContext {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public bool $ensureArray;
 | 
				
			||||||
 | 
					  public bool $ensureAssoc;
 | 
				
			||||||
 | 
					  public bool $ensureKeys;
 | 
				
			||||||
 | 
					  public bool $ensureOrder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function resetParams(?array $params): void {
 | 
				
			||||||
 | 
					    parent::resetParams($params);
 | 
				
			||||||
 | 
					    $this->ensureArray = $params["ensure_array"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_array"][1];
 | 
				
			||||||
 | 
					    $this->ensureAssoc = $params["ensure_assoc"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_assoc"][1];
 | 
				
			||||||
 | 
					    $this->ensureKeys = $params["ensure_keys"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_keys"][1];
 | 
				
			||||||
 | 
					    $this->ensureOrder = $params["ensure_order"] ?? ref_schema::ASSOC_PARAMS_SCHEMA["ensure_order"][1];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public ?ScalarWrapper $arrayWrapper = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** liste des clés valides */
 | 
				
			||||||
 | 
					  public array $keys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @var Wrapper[] */
 | 
				
			||||||
 | 
					  public array $keyWrappers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** @var string|int|null clé sélectionnée */
 | 
				
			||||||
 | 
					  public $selectedKey = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** résultat consolidé de l'analyse du tableau et de ses composants */
 | 
				
			||||||
 | 
					  public ConsolidatedResult $consolidatedResult;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,53 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nur\sery\wip\schema\_list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nulib\ValueException;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ListResult extends Result {
 | 
					 | 
				
			||||||
  function __construct(Result $arrayResult, array &$keyResults) {
 | 
					 | 
				
			||||||
    $this->arrayResult = $arrayResult;
 | 
					 | 
				
			||||||
    $this->keyResults =& $keyResults;
 | 
					 | 
				
			||||||
    $this->result =& $this->arrayResult;
 | 
					 | 
				
			||||||
      parent::__construct();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function isList(?ListResult &$result=null): bool { $result = $this; return true;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected Result $arrayResult;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var Result[] */
 | 
					 | 
				
			||||||
  protected array $keyResults;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getKeys(): array {
 | 
					 | 
				
			||||||
    return array_keys($this->keyResults);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected Result $result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function select($key): Result {
 | 
					 | 
				
			||||||
    if ($key === null) {
 | 
					 | 
				
			||||||
      $this->result =& $this->arrayResult;
 | 
					 | 
				
			||||||
    } elseif (array_key_exists($key, $this->keyResults)) {
 | 
					 | 
				
			||||||
      $this->result =& $this->keyResults[$key];
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      throw ValueException::invalid_key($key);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return $this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function reset(): void {
 | 
					 | 
				
			||||||
    $this->arrayResult->reset();
 | 
					 | 
				
			||||||
    foreach ($this->keyResults as $result) {
 | 
					 | 
				
			||||||
      $result->reset();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function __get(string $name) {
 | 
					 | 
				
			||||||
    return $this->result[$name];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function __set(string $name, $value): void {
 | 
					 | 
				
			||||||
    $this->result[$name] = $value;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,9 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\_list;
 | 
					namespace nulib\schema\_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\ref\schema\ref_schema;
 | 
					use nulib\ref\schema\ref_schema;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\Wrapper;
 | 
					use nulib\schema\Wrapper;
 | 
				
			||||||
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ListSchema extends Schema {
 | 
					class ListSchema extends Schema {
 | 
				
			||||||
  /** @var array meta-schema d'un schéma de nature liste */
 | 
					  /** @var array meta-schema d'un schéma de nature liste */
 | 
				
			||||||
@ -34,7 +35,7 @@ class ListSchema extends Schema {
 | 
				
			|||||||
        "schema" => $definition[0],
 | 
					        "schema" => $definition[0],
 | 
				
			||||||
      ];
 | 
					      ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    self::_normalize($definition, $definitionKey);
 | 
					    self::_normalize_definition($definition, $definitionKey);
 | 
				
			||||||
    self::_ensure_nature($definition, "list", "array");
 | 
					    self::_ensure_nature($definition, "list", "array");
 | 
				
			||||||
    return $definition;
 | 
					    return $definition;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -50,17 +51,26 @@ class ListSchema extends Schema {
 | 
				
			|||||||
    $this->definition = $definition;
 | 
					    $this->definition = $definition;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isList(?ListSchema &$schema=null): bool {
 | 
					  const KEYS = [null];
 | 
				
			||||||
    $schema = $this;
 | 
					
 | 
				
			||||||
    return true;
 | 
					  function getKeys(): array {
 | 
				
			||||||
 | 
					    return self::KEYS;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public function getSchema($key=false): Schema {
 | 
				
			||||||
 | 
					    if ($key !== null) throw ValueException::invalid_key($key);
 | 
				
			||||||
 | 
					    return $this;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function newWrapper(): ListWrapper {
 | 
					  protected function newWrapper(): ListWrapper {
 | 
				
			||||||
    return new ListWrapper($this);
 | 
					    return new ListWrapper($this);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): ListWrapper {
 | 
					  function getWrapper(&$value=null, $valueKey=null, ?array $params = null, ?Wrapper &$wrapper=null): ListWrapper {
 | 
				
			||||||
 | 
					    # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception
 | 
				
			||||||
 | 
					    # cf le code similaire dans ScalarWrapper::__construct()
 | 
				
			||||||
 | 
					    $verifix = $value !== null || $wrapper !== null;
 | 
				
			||||||
    if (!($wrapper instanceof ListWrapper)) $wrapper = $this->newWrapper();
 | 
					    if (!($wrapper instanceof ListWrapper)) $wrapper = $this->newWrapper();
 | 
				
			||||||
    return $wrapper->reset($value, $valueKey);
 | 
					    return $wrapper->reset($value, $valueKey, $verifix);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\_list;
 | 
					namespace nulib\schema\_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					use nulib\schema\Result;
 | 
				
			||||||
use nur\sery\wip\schema\Wrapper;
 | 
					use nulib\schema\Wrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract/*XXX*/ class ListWrapper extends Wrapper {
 | 
					abstract/*XXX*/ class ListWrapper extends Wrapper {
 | 
				
			||||||
  function isList(?ListWrapper &$wrapper=null): bool { $wrapper = $this; return true; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function ensureKeys(): bool {
 | 
					  function ensureKeys(): bool {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,164 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nur\sery\wip\schema\_scalar;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use nulib\cl;
 | 
					 | 
				
			||||||
use nulib\ref\schema\ref_analyze;
 | 
					 | 
				
			||||||
use nulib\ref\schema\ref_schema;
 | 
					 | 
				
			||||||
use nulib\ValueException;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use Throwable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Class ScalarResult: résultat de l'analyse ou de la normalisation d'une valeur
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class ScalarResult extends Result {
 | 
					 | 
				
			||||||
  function isScalar(?ScalarResult &$result=null): bool { $result = $this; return true; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getKeys(): array {
 | 
					 | 
				
			||||||
    return [null];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function select($key): Result {
 | 
					 | 
				
			||||||
    if ($key !== null) throw ValueException::invalid_key($key);
 | 
					 | 
				
			||||||
    return $this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var array  */
 | 
					 | 
				
			||||||
  protected $result;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  function reset(): void {
 | 
					 | 
				
			||||||
    $this->result = array_merge(
 | 
					 | 
				
			||||||
      array_fill_keys(static::KEYS, null), [
 | 
					 | 
				
			||||||
      "resultAvailable" => false,
 | 
					 | 
				
			||||||
      "present" => false,
 | 
					 | 
				
			||||||
      "available" => false,
 | 
					 | 
				
			||||||
      "null" => false,
 | 
					 | 
				
			||||||
      "valid" => false,
 | 
					 | 
				
			||||||
      "normalized" => false,
 | 
					 | 
				
			||||||
    ]);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function __get(string $name) {
 | 
					 | 
				
			||||||
    return $this->result[$name];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function __set(string $name, $value): void {
 | 
					 | 
				
			||||||
    $this->result[$name] = $value;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected static function replace_key(string &$message, ?string $key): void {
 | 
					 | 
				
			||||||
    if ($key) {
 | 
					 | 
				
			||||||
      $message = str_replace("{key}", $key, $message);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $message = str_replace("{key}: ", "", $message);
 | 
					 | 
				
			||||||
      $message = str_replace("cette valeur", "la valeur", $message);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected static function replace_orig(string &$message, $origValue): void {
 | 
					 | 
				
			||||||
    $message = str_replace("{orig}", strval($origValue), $message);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected function getMessage(string $key, ScalarSchema $schema): string {
 | 
					 | 
				
			||||||
    $message = cl::get($schema->messages, $key);
 | 
					 | 
				
			||||||
    if ($message !== null) return $message;
 | 
					 | 
				
			||||||
    return cl::get(ref_schema::MESSAGES, $key);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function setMissing(ScalarSchema $schema): int {
 | 
					 | 
				
			||||||
    $this->resultAvailable = true;
 | 
					 | 
				
			||||||
    $this->present = false;
 | 
					 | 
				
			||||||
    $this->available = false;
 | 
					 | 
				
			||||||
    if (!$schema->required) {
 | 
					 | 
				
			||||||
      $this->null = false;
 | 
					 | 
				
			||||||
      $this->valid = true;
 | 
					 | 
				
			||||||
      $this->normalized = true;
 | 
					 | 
				
			||||||
      return ref_analyze::NORMALIZED;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $messageKey = $this->messageKey = "missing";
 | 
					 | 
				
			||||||
      $message = $this->getMessage($messageKey, $schema);
 | 
					 | 
				
			||||||
      self::replace_key($message, $schema->name);
 | 
					 | 
				
			||||||
      $this->message = $message;
 | 
					 | 
				
			||||||
      return ref_analyze::MISSING;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function setUnavailable(ScalarSchema $schema): int {
 | 
					 | 
				
			||||||
    $this->resultAvailable = true;
 | 
					 | 
				
			||||||
    $this->present = true;
 | 
					 | 
				
			||||||
    $this->available = false;
 | 
					 | 
				
			||||||
    if (!$schema->required) {
 | 
					 | 
				
			||||||
      $this->null = false;
 | 
					 | 
				
			||||||
      $this->valid = true;
 | 
					 | 
				
			||||||
      $this->normalized = true;
 | 
					 | 
				
			||||||
      return ref_analyze::NORMALIZED;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $messageKey = $this->messageKey = "unavailable";
 | 
					 | 
				
			||||||
      $message = $this->getMessage($messageKey, $schema);
 | 
					 | 
				
			||||||
      self::replace_key($message, $schema->name);
 | 
					 | 
				
			||||||
      $this->message = $message;
 | 
					 | 
				
			||||||
      return ref_analyze::UNAVAILABLE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function setNull(ScalarSchema $schema): int {
 | 
					 | 
				
			||||||
    $this->resultAvailable = true;
 | 
					 | 
				
			||||||
    $this->present = true;
 | 
					 | 
				
			||||||
    $this->available = true;
 | 
					 | 
				
			||||||
    $this->null = true;
 | 
					 | 
				
			||||||
    if ($schema->nullable) {
 | 
					 | 
				
			||||||
      $this->valid = true;
 | 
					 | 
				
			||||||
      $this->normalized = true;
 | 
					 | 
				
			||||||
      return ref_analyze::NORMALIZED;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $messageKey = $this->messageKey = "null";
 | 
					 | 
				
			||||||
      $message = $this->getMessage($messageKey, $schema);
 | 
					 | 
				
			||||||
      self::replace_key($message, $schema->name);
 | 
					 | 
				
			||||||
      $this->message = $message;
 | 
					 | 
				
			||||||
      return ref_analyze::NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function setInvalid($value, ScalarSchema $schema, ?Throwable $t=null): int {
 | 
					 | 
				
			||||||
    $this->resultAvailable = true;
 | 
					 | 
				
			||||||
    $this->present = true;
 | 
					 | 
				
			||||||
    $this->available = true;
 | 
					 | 
				
			||||||
    $this->null = false;
 | 
					 | 
				
			||||||
    $this->valid = false;
 | 
					 | 
				
			||||||
    $this->origValue = $value;
 | 
					 | 
				
			||||||
    $messageKey = $this->messageKey = "invalid";
 | 
					 | 
				
			||||||
    $message = $this->getMessage($messageKey, $schema);
 | 
					 | 
				
			||||||
    self::replace_key($message, $schema->name);
 | 
					 | 
				
			||||||
    self::replace_orig($message, $schema->orig);
 | 
					 | 
				
			||||||
    if ($t !== null) {
 | 
					 | 
				
			||||||
      $tmessage = ValueException::get_message($t);
 | 
					 | 
				
			||||||
      if ($tmessage) $message .= ": $tmessage";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $this->message = $message;
 | 
					 | 
				
			||||||
    return ref_analyze::INVALID;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function setValid($normalizedValue=null): int {
 | 
					 | 
				
			||||||
    $this->resultAvailable = true;
 | 
					 | 
				
			||||||
    $this->present = true;
 | 
					 | 
				
			||||||
    $this->available = true;
 | 
					 | 
				
			||||||
    $this->null = false;
 | 
					 | 
				
			||||||
    $this->valid = true;
 | 
					 | 
				
			||||||
    $this->normalizedValue = $normalizedValue;
 | 
					 | 
				
			||||||
    return ref_analyze::VALID;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function setNormalized(): int {
 | 
					 | 
				
			||||||
    $this->resultAvailable = true;
 | 
					 | 
				
			||||||
    $this->present = true;
 | 
					 | 
				
			||||||
    $this->available = true;
 | 
					 | 
				
			||||||
    $this->null = false;
 | 
					 | 
				
			||||||
    $this->valid = true;
 | 
					 | 
				
			||||||
    $this->normalized = true;
 | 
					 | 
				
			||||||
    return ref_analyze::NORMALIZED;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function throw(bool $throw): void {
 | 
					 | 
				
			||||||
    if ($throw) throw new ValueException($this->message);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,41 +1,18 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\_scalar;
 | 
					namespace nulib\schema\_scalar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\ref\schema\ref_schema;
 | 
					use nulib\ref\schema\ref_schema;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\types\IType;
 | 
					use nulib\schema\Wrapper;
 | 
				
			||||||
use nur\sery\wip\schema\Wrapper;
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class ScalarSchema
 | 
					 * Class ScalarSchema
 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * @property-read array|IType $type
 | 
					 | 
				
			||||||
 * @property-read mixed $default
 | 
					 | 
				
			||||||
 * @property-read string|null $title
 | 
					 | 
				
			||||||
 * @property-read bool $required
 | 
					 | 
				
			||||||
 * @property-read bool $nullable
 | 
					 | 
				
			||||||
 * @property-read string|array|null $desc
 | 
					 | 
				
			||||||
 * @property-read callable|null $analyzerFunc
 | 
					 | 
				
			||||||
 * @property-read callable|null $extractorFunc
 | 
					 | 
				
			||||||
 * @property-read callable|null $parserFunc
 | 
					 | 
				
			||||||
 * @property-read callable|null $normalizerFunc
 | 
					 | 
				
			||||||
 * @property-read array|null $messages
 | 
					 | 
				
			||||||
 * @property-read callable|null $formatterFunc
 | 
					 | 
				
			||||||
 * @property-read mixed $format
 | 
					 | 
				
			||||||
 * @property-read array $nature
 | 
					 | 
				
			||||||
 * @property-read array|null $schema
 | 
					 | 
				
			||||||
 * @property-read string|int|null $name
 | 
					 | 
				
			||||||
 * @property-read string|array|null $pkey
 | 
					 | 
				
			||||||
 * @property-read string|null $header
 | 
					 | 
				
			||||||
 * @property-read bool|null $composite
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class ScalarSchema extends Schema {
 | 
					class ScalarSchema extends Schema {
 | 
				
			||||||
  /** @var array meta-schema d'un schéma de nature scalaire */
 | 
					 | 
				
			||||||
  const METASCHEMA = ref_schema::SCALAR_METASCHEMA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * indiquer si $definition est une définition de schéma scalaire que
 | 
					   * indiquer si $definition est une définition de schéma scalaire que
 | 
				
			||||||
   * {@link normalize()} pourrait normaliser
 | 
					   * {@link normalize_definition()} pourrait normaliser
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  static function isa_definition($definition): bool {
 | 
					  static function isa_definition($definition): bool {
 | 
				
			||||||
    # chaine ou null
 | 
					    # chaine ou null
 | 
				
			||||||
@ -64,8 +41,9 @@ class ScalarSchema extends Schema {
 | 
				
			|||||||
    return $haveIndex0 && $count > 1;
 | 
					    return $haveIndex0 && $count > 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static function normalize($definition, $definitionKey=null): array {
 | 
					  static function normalize_definition($definition, $definitionKey=null): array {
 | 
				
			||||||
    self::_normalize($definition, $definitionKey);
 | 
					    $natureMetaschema = array_merge(ref_schema::NATURE_METASCHEMA, ref_schema::SCALAR_NATURE_METASCHEMA);
 | 
				
			||||||
 | 
					    self::_normalize_definition($definition, $definitionKey, $natureMetaschema);
 | 
				
			||||||
    self::_ensure_nature($definition, "scalar");
 | 
					    self::_ensure_nature($definition, "scalar");
 | 
				
			||||||
    return $definition;
 | 
					    return $definition;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -73,40 +51,47 @@ class ScalarSchema extends Schema {
 | 
				
			|||||||
  function __construct($definition=null, $definitionKey=null, bool $normalize=true) {
 | 
					  function __construct($definition=null, $definitionKey=null, bool $normalize=true) {
 | 
				
			||||||
    if ($definition === null) $definition = static::SCHEMA;
 | 
					    if ($definition === null) $definition = static::SCHEMA;
 | 
				
			||||||
    if ($normalize) {
 | 
					    if ($normalize) {
 | 
				
			||||||
      $definition = self::normalize($definition, $definitionKey);
 | 
					      $definition = self::normalize_definition($definition, $definitionKey);
 | 
				
			||||||
      $this->_definition = $definition;
 | 
					      $this->_definition = $definition;
 | 
				
			||||||
      self::_ensure_type($definition);
 | 
					      self::_ensure_type($definition);
 | 
				
			||||||
      self::_ensure_schema_instances($definition);
 | 
					      self::_ensure_schema_instances($definition);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      # ici, $definition contient un schema déjà instancié, mais c'est le mieux
 | 
				
			||||||
 | 
					      # qu'on puisse faire
 | 
				
			||||||
 | 
					      $this->_definition = $definition;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $this->definition = $definition;
 | 
					    $this->definition = $definition;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isScalar(?ScalarSchema &$schema=null): bool {
 | 
					  const KEYS = [];
 | 
				
			||||||
    $schema = $this;
 | 
					
 | 
				
			||||||
    return true;
 | 
					  function getKeys(): array {
 | 
				
			||||||
 | 
					    return self::KEYS;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getSchema($key=false): Schema {
 | 
				
			||||||
 | 
					    if ($key === false || $key === null || $key === "") return $this;
 | 
				
			||||||
 | 
					    throw ValueException::invalid_key($key);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function newWrapper(): ScalarWrapper {
 | 
					  protected function newWrapper(): ScalarWrapper {
 | 
				
			||||||
    return new ScalarWrapper($this);
 | 
					    return new ScalarWrapper($this);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getWrapper(&$value=null, $valueKey=null, ?Wrapper &$wrapper=null): ScalarWrapper {
 | 
					  function getWrapper(&$value=null, $valueKey=null, ?array $params=null, ?Wrapper &$wrapper=null): ScalarWrapper {
 | 
				
			||||||
    # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception
 | 
					    # si pas de valeur ni de wrapper, pas de vérification et donc pas d'exception
 | 
				
			||||||
    # cf le code similaire dans ScalarWrapper::__construct()
 | 
					    # cf le code similaire dans ScalarWrapper::__construct()
 | 
				
			||||||
    $verifix = $value !== null || $wrapper !== null;
 | 
					    $dontAnalyze = $value === null && $wrapper === null;
 | 
				
			||||||
    if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper();
 | 
					    if (!($wrapper instanceof ScalarWrapper)) $wrapper = $this->newWrapper();
 | 
				
			||||||
    return $wrapper->reset($value, $valueKey, $verifix);
 | 
					
 | 
				
			||||||
 | 
					    # la nature du schéma peut contenir des paramètres par défaut
 | 
				
			||||||
 | 
					    $nature = $this->definition[""];
 | 
				
			||||||
 | 
					    foreach (array_keys(ref_schema::SCALAR_PARAMS_SCHEMA) as $paramKey) {
 | 
				
			||||||
 | 
					      $paramValue = $nature[$paramKey] ?? null;
 | 
				
			||||||
 | 
					      if ($paramValue !== null) $params[$paramKey] = $paramValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ($params !== null) $wrapper->resetParams($params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return $wrapper->reset($value, $valueKey, $dontAnalyze? ["analyze" => false]: null);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  #############################################################################
 | 
					 | 
				
			||||||
  # key & properties
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const _PROPERTY_PKEYS = [
 | 
					 | 
				
			||||||
    "analyzerFunc" => "analyzer_func",
 | 
					 | 
				
			||||||
    "extractorFunc" => "extractor_func",
 | 
					 | 
				
			||||||
    "parserFunc" => "parser_func",
 | 
					 | 
				
			||||||
    "normalizerFunc" => "normalizer_func",
 | 
					 | 
				
			||||||
    "formatterFunc" => "formatter_func",
 | 
					 | 
				
			||||||
    "nature" => ["", 0],
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,85 +1,56 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\_scalar;
 | 
					namespace nulib\schema\_scalar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\php\func;
 | 
					use nulib\php\func;
 | 
				
			||||||
use nulib\ref\schema\ref_analyze;
 | 
					use nulib\ref\schema\ref_analyze;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
 | 
					use nulib\schema\types;
 | 
				
			||||||
 | 
					use nulib\schema\types\IType;
 | 
				
			||||||
 | 
					use nulib\schema\Wrapper;
 | 
				
			||||||
 | 
					use nulib\schema\WrapperContext;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\sery\wip\schema\WrapperContext;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\IType;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Wrapper;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class ScalarWrapper
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @method ScalarWrapper reset(&$value, $valueKey=null, ?array $params=null)
 | 
				
			||||||
 | 
					 * @method self set($value, ?array $params=null, $key=false)
 | 
				
			||||||
 | 
					 * @method self unset(?array $params=null, $key=false)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class ScalarWrapper extends Wrapper {
 | 
					class ScalarWrapper extends Wrapper {
 | 
				
			||||||
  function __construct(ScalarSchema $schema, &$value=null, $valueKey=null, ?array $params=null) {
 | 
					  function __construct(Schema $schema, &$value=null, $valueKey=null, ?array $params=null, ?WrapperContext $context=null) {
 | 
				
			||||||
    $verifix = $params["verifix"] ?? true;
 | 
					    if ($context === null) $context = new WrapperContext($schema, null, null, $params);
 | 
				
			||||||
    $throw = $params["throw"] ?? null;
 | 
					    $context->result = new Result();
 | 
				
			||||||
    if ($value !== null && $throw === null) {
 | 
					    $this->context = $context;
 | 
				
			||||||
      # Si $value est null, ne pas lancer d'exception, parce qu'on considère que
 | 
					
 | 
				
			||||||
      # c'est une initialisation sans conséquences
 | 
					    if ($value !== null) {
 | 
				
			||||||
      $throw = true;
 | 
					      # n'initialiser que si $value n'est pas null
 | 
				
			||||||
 | 
					      $this->reset($value, $valueKey);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      # il faut au moins que le type soit disponible
 | 
				
			||||||
 | 
					      $this->resetContext(false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $this->verifix = $verifix;
 | 
					 | 
				
			||||||
    $this->throw = $throw ?? false;
 | 
					 | 
				
			||||||
    $this->schema = $schema;
 | 
					 | 
				
			||||||
    $this->result = new ScalarResult();
 | 
					 | 
				
			||||||
    $this->reset($value, $valueKey);
 | 
					 | 
				
			||||||
    $this->throw = $throw ?? true;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isScalar(?ScalarWrapper &$wrapper=null): bool { $wrapper = $this; return true; }
 | 
					  protected WrapperContext $context;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected bool $verifix;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected bool $throw;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** schéma de cette valeur */
 | 
					 | 
				
			||||||
  protected ScalarSchema $schema;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** source et destination de la valeur */
 | 
					 | 
				
			||||||
  protected Input $input;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** @var string|int|null clé de la valeur dans le tableau destination */
 | 
					 | 
				
			||||||
  protected $valueKey;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** type de la valeur après analyse */
 | 
					 | 
				
			||||||
  protected ?IType $type;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** résultat de l'analyse de la valeur */
 | 
					 | 
				
			||||||
  protected ScalarResult $result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected function newInput(&$value): Input {
 | 
					 | 
				
			||||||
    return new Input($value);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function reset(&$value, $valueKey=null, ?bool $verifix=null): Wrapper {
 | 
					 | 
				
			||||||
    if ($value instanceof Input) $input = $value;
 | 
					 | 
				
			||||||
    else $input = $this->newInput($value);
 | 
					 | 
				
			||||||
    $this->input = $input;
 | 
					 | 
				
			||||||
    $this->valueKey = $valueKey;
 | 
					 | 
				
			||||||
    $this->type = null;
 | 
					 | 
				
			||||||
    $this->analyze();
 | 
					 | 
				
			||||||
    if ($verifix ?? $this->verifix) $this->verifix();
 | 
					 | 
				
			||||||
    return $this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getKeys(): array {
 | 
					  function getKeys(): array {
 | 
				
			||||||
    return [null];
 | 
					    return ScalarSchema::KEYS;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @param string|int|null $key */
 | 
					  /** @param string|int|null $key */
 | 
				
			||||||
  function select($key): ScalarWrapper {
 | 
					  function select($key=null): ScalarWrapper {
 | 
				
			||||||
    if ($key !== null) throw ValueException::invalid_key($key);
 | 
					    if ($key === null || $key === "") return $this;
 | 
				
			||||||
    return $this;
 | 
					    throw ValueException::invalid_key($key);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** analyser la valeur et résoudre son type */
 | 
					  /** analyser la valeur et résoudre son type */
 | 
				
			||||||
  protected function analyze0(WrapperContext $context): int {
 | 
					  protected static function _analyze0(WrapperContext $context): int {
 | 
				
			||||||
    /** @var ScalarSchema $schema */
 | 
					    /** @var ScalarSchema $schema */
 | 
				
			||||||
    $schema = $context->schema;
 | 
					    $schema = $context->schema;
 | 
				
			||||||
    $input = $context->input;
 | 
					    $input = $context->input;
 | 
				
			||||||
    $valueKey = $context->valueKey;
 | 
					    $valueKey = $context->valueKey;
 | 
				
			||||||
    /** @var ScalarResult $result */
 | 
					 | 
				
			||||||
    $result = $context->result;
 | 
					    $result = $context->result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $default = $schema->default;
 | 
					    $default = $schema->default;
 | 
				
			||||||
@ -112,7 +83,7 @@ class ScalarWrapper extends Wrapper {
 | 
				
			|||||||
          $args = $name;
 | 
					          $args = $name;
 | 
				
			||||||
          $name = $key;
 | 
					          $name = $key;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $type = types::get($schema->nullable, $name, $args, $this->schema->getDefinition());
 | 
					        $type = types::get($schema->nullable, $name, $args, $schema->getDefinition());
 | 
				
			||||||
        if ($firstType === null) $firstType = $type;
 | 
					        if ($firstType === null) $firstType = $type;
 | 
				
			||||||
        $types[] = $type;
 | 
					        $types[] = $type;
 | 
				
			||||||
        if ($type->isAvailable($input, $valueKey)) {
 | 
					        if ($type->isAvailable($input, $valueKey)) {
 | 
				
			||||||
@ -140,7 +111,7 @@ class ScalarWrapper extends Wrapper {
 | 
				
			|||||||
        $type = $firstType;
 | 
					        $type = $firstType;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $context->type = $this->type = $type;
 | 
					    $context->type = $type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!$type->isAvailable($input, $valueKey)) {
 | 
					    if (!$type->isAvailable($input, $valueKey)) {
 | 
				
			||||||
      if ($default !== null) {
 | 
					      if ($default !== null) {
 | 
				
			||||||
@ -152,6 +123,16 @@ class ScalarWrapper extends Wrapper {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $value = $input->get($valueKey);
 | 
					    $value = $input->get($valueKey);
 | 
				
			||||||
 | 
					    $missing = $type->getMissingValue($haveMissing);
 | 
				
			||||||
 | 
					    if ($haveMissing && $value === $missing) {
 | 
				
			||||||
 | 
					      if ($default !== null) {
 | 
				
			||||||
 | 
					        $input->set($default, $valueKey);
 | 
				
			||||||
 | 
					        return $result->setNormalized();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return $result->setMissing($schema);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $context->origValue = $context->value = $value;
 | 
					    $context->origValue = $context->value = $value;
 | 
				
			||||||
    if ($type->isNull($value)) {
 | 
					    if ($type->isNull($value)) {
 | 
				
			||||||
      return $result->setNull($schema);
 | 
					      return $result->setNull($schema);
 | 
				
			||||||
@ -165,25 +146,27 @@ class ScalarWrapper extends Wrapper {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function analyze(): int {
 | 
					  /**
 | 
				
			||||||
    $schema = $this->schema;
 | 
					   * @param ScalarWrapper $wrapper
 | 
				
			||||||
    $input = $this->input;
 | 
					   */
 | 
				
			||||||
    $valueKey = $this->valueKey;
 | 
					  static function _analyze(WrapperContext $context, Wrapper $wrapper, ?array $params): int {
 | 
				
			||||||
    $result = $this->result;
 | 
					    /** @var ScalarSchema $schema */
 | 
				
			||||||
    $result->reset();
 | 
					    $schema = $context->schema;
 | 
				
			||||||
    $context = new WrapperContext($schema, $this, $input, $valueKey, $result);
 | 
					    $input = $context->input;
 | 
				
			||||||
 | 
					    $valueKey = $context->valueKey;
 | 
				
			||||||
 | 
					    $result = $context->result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** @var func $analyzerFunc */
 | 
					    /** @var func $analyzerFunc */
 | 
				
			||||||
    $analyzerFunc = $schema->analyzerFunc;
 | 
					    $analyzerFunc = $schema->analyzerFunc;
 | 
				
			||||||
    if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context]);
 | 
					    if ($analyzerFunc !== null) $what = $analyzerFunc->invoke([$context, $wrapper]);
 | 
				
			||||||
    else $what = $this->analyze0($context);
 | 
					    else $what = self::_analyze0($context);
 | 
				
			||||||
    if ($what !== ref_analyze::STRING) return $what;
 | 
					    if ($what !== ref_analyze::STRING) return $what;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $value = $context->value;
 | 
					    $value = $context->value;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      /** @var func $extractorFunc */
 | 
					      /** @var func $extractorFunc */
 | 
				
			||||||
      $extractorFunc = $schema->extractorFunc;
 | 
					      $extractorFunc = $schema->extractorFunc;
 | 
				
			||||||
      if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$value, $context]);
 | 
					      if ($extractorFunc !== null) $extracted = $extractorFunc->invoke([$value, $context, $wrapper]);
 | 
				
			||||||
      else $extracted = $context->type->extract($value);
 | 
					      else $extracted = $context->type->extract($value);
 | 
				
			||||||
      $context->value = $extracted;
 | 
					      $context->value = $extracted;
 | 
				
			||||||
    } catch (ValueException $e) {
 | 
					    } catch (ValueException $e) {
 | 
				
			||||||
@ -194,7 +177,7 @@ class ScalarWrapper extends Wrapper {
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
      /** @var func $parserFunc */
 | 
					      /** @var func $parserFunc */
 | 
				
			||||||
      $parserFunc = $schema->parserFunc;
 | 
					      $parserFunc = $schema->parserFunc;
 | 
				
			||||||
      if ($parserFunc !== null) $parsed = $parserFunc->invoke([$extracted, $context]);
 | 
					      if ($parserFunc !== null) $parsed = $parserFunc->invoke([$extracted, $context, $wrapper]);
 | 
				
			||||||
      else $parsed = $context->type->parse($extracted);
 | 
					      else $parsed = $context->type->parse($extracted);
 | 
				
			||||||
      $context->value = $parsed;
 | 
					      $context->value = $parsed;
 | 
				
			||||||
    } catch (ValueException $e) {
 | 
					    } catch (ValueException $e) {
 | 
				
			||||||
@ -211,107 +194,52 @@ class ScalarWrapper extends Wrapper {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function verifix(?bool $throw=null): bool {
 | 
					  /**
 | 
				
			||||||
    $result = $this->result;
 | 
					   * @param ScalarWrapper $wrapper
 | 
				
			||||||
    $valueKey = $this->valueKey;
 | 
					   */
 | 
				
			||||||
    $verifix = false;
 | 
					  static function _normalize(WrapperContext $context, Wrapper $wrapper, ?array $params): bool {
 | 
				
			||||||
 | 
					    /** @var ScalarSchema $schema */
 | 
				
			||||||
 | 
					    $schema = $context->schema;
 | 
				
			||||||
 | 
					    $input = $context->input;
 | 
				
			||||||
 | 
					    $valueKey = $context->valueKey;
 | 
				
			||||||
 | 
					    $result = $context->result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $normalize = false;
 | 
				
			||||||
    $modified = false;
 | 
					    $modified = false;
 | 
				
			||||||
    if ($result->resultAvailable) {
 | 
					    if ($result->resultAvailable) {
 | 
				
			||||||
      if ($result->null) {
 | 
					      if ($result->null) {
 | 
				
			||||||
        # forcer la valeur null, parce que la valeur actuelle est peut-être une
 | 
					        # forcer la valeur null, parce que la valeur actuelle est peut-être une
 | 
				
			||||||
        # valeur assimilée à null
 | 
					        # valeur assimilée à null
 | 
				
			||||||
        $this->input->set(null, $valueKey);
 | 
					        $input->set(null, $valueKey);
 | 
				
			||||||
      } elseif ($result->valid && !$result->normalized) {
 | 
					      } elseif ($result->valid && !$result->normalized) {
 | 
				
			||||||
        $normalizedValue = $result->normalizedValue;
 | 
					        $normalizedValue = $result->normalizedValue;
 | 
				
			||||||
        if ($normalizedValue !== null) {
 | 
					        if ($normalizedValue !== null) {
 | 
				
			||||||
          # la valeur normalisée est disponible
 | 
					          # la valeur normalisée est disponible
 | 
				
			||||||
          $this->input->set($normalizedValue);
 | 
					          $input->set($normalizedValue, $valueKey);
 | 
				
			||||||
          $result->normalizedValue = null;
 | 
					          $result->normalizedValue = null;
 | 
				
			||||||
          $modified = true;
 | 
					          $modified = true;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          # normaliser la valeur
 | 
					          # normaliser la valeur
 | 
				
			||||||
          $verifix = true;
 | 
					          $normalize = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      $verifix = true;
 | 
					      $normalize = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ($verifix) {
 | 
					    if ($normalize) {
 | 
				
			||||||
      $value = $this->input->get($valueKey);
 | 
					      $value = $input->get($valueKey);
 | 
				
			||||||
      $schema = $this->schema;
 | 
					 | 
				
			||||||
      /** @var func $normalizerFunc */
 | 
					      /** @var func $normalizerFunc */
 | 
				
			||||||
      $normalizerFunc = $schema->normalizerFunc;
 | 
					      $normalizerFunc = $schema->normalizerFunc;
 | 
				
			||||||
      if ($normalizerFunc !== null) {
 | 
					      if ($normalizerFunc !== null) {
 | 
				
			||||||
        $context = new WrapperContext($schema, $this, $this->input, $valueKey, $result);
 | 
					 | 
				
			||||||
        $orig = $value;
 | 
					        $orig = $value;
 | 
				
			||||||
        $value = $normalizerFunc->invoke([$orig, $context]);
 | 
					        $value = $normalizerFunc->invoke([$orig, $context, $wrapper]);
 | 
				
			||||||
        $modified = $value !== $orig;
 | 
					        $modified = $value !== $orig;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        $modified = $this->type->verifix($value, $result, $this->schema);
 | 
					        $modified = $context->type->normalize($value, $result, $schema);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if ($result->valid) $this->input->set($value, $valueKey);
 | 
					      if ($result->valid) $input->set($value, $valueKey);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!$result->valid) $result->throw($throw ?? $this->throw);
 | 
					 | 
				
			||||||
    return $modified;
 | 
					    return $modified;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getResult(): ScalarResult {
 | 
					 | 
				
			||||||
    return $this->result;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function isPresent(): bool {
 | 
					 | 
				
			||||||
    return $this->result->present;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getType(): IType {
 | 
					 | 
				
			||||||
    return $this->type;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function isAvailable(): bool {
 | 
					 | 
				
			||||||
    return $this->result->available;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function isValid(): bool {
 | 
					 | 
				
			||||||
    return $this->result->valid;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function isNormalized(): bool {
 | 
					 | 
				
			||||||
    return $this->result->normalized;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function get($default=null) {
 | 
					 | 
				
			||||||
    if ($this->result->available) return $this->input->get($this->valueKey);
 | 
					 | 
				
			||||||
    else return $default;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function set($value, ?bool $verifix=null): ScalarWrapper {
 | 
					 | 
				
			||||||
    $this->input->set($value, $this->valueKey);
 | 
					 | 
				
			||||||
    $this->analyze();
 | 
					 | 
				
			||||||
    if ($verifix ?? $this->verifix) $this->verifix();
 | 
					 | 
				
			||||||
    return $this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function unset(?bool $verifix=null): ScalarWrapper {
 | 
					 | 
				
			||||||
    $this->input->unset($this->valueKey);
 | 
					 | 
				
			||||||
    $this->analyze();
 | 
					 | 
				
			||||||
    if ($verifix ?? $this->verifix) $this->verifix();
 | 
					 | 
				
			||||||
    return $this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function format($format=null): string {
 | 
					 | 
				
			||||||
    $value = $this->input->get($this->valueKey);
 | 
					 | 
				
			||||||
    /** @var func $formatterFunc */
 | 
					 | 
				
			||||||
    $formatterFunc = $this->schema->formatterFunc;
 | 
					 | 
				
			||||||
    if ($formatterFunc !== null) {
 | 
					 | 
				
			||||||
      # la fonction formatter n'a pas forcément accès au format de la définition
 | 
					 | 
				
			||||||
      # le lui fournir ici
 | 
					 | 
				
			||||||
      $format ??= $this->schema->format;
 | 
					 | 
				
			||||||
      return $formatterFunc->invoke([$value, $format]);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      # on assume que le type a été initialisé avec le format de la définition
 | 
					 | 
				
			||||||
      # le cas échéant
 | 
					 | 
				
			||||||
      return $this->type->format($value, $format);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,11 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\input;
 | 
					namespace nulib\schema\input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#XXX implémenter le renommage de paramètres et faire des méthodes pour
 | 
					#XXX implémenter le renommage de paramètres et faire des méthodes pour
 | 
				
			||||||
# construire des querystring et paramètres de formulaires
 | 
					# construire des querystring et paramètres de formulaires
 | 
				
			||||||
use nur\sery\wip\php\access\FormAccess;
 | 
					use nulib\php\access\FormAccess;
 | 
				
			||||||
use nur\sery\wip\php\access\IAccess;
 | 
					use nulib\php\access\IAccess;
 | 
				
			||||||
use nur\sery\wip\php\access\KeyAccess;
 | 
					use nulib\php\access\ShadowAccess;
 | 
				
			||||||
use nur\sery\wip\php\access\ShadowAccess;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class FormInput: accès à des paramètres de formulaire (POST ou GET, dans cet
 | 
					 * Class FormInput: accès à des paramètres de formulaire (POST ou GET, dans cet
 | 
				
			||||||
@ -18,15 +17,14 @@ use nur\sery\wip\php\access\ShadowAccess;
 | 
				
			|||||||
class FormInput extends Input {
 | 
					class FormInput extends Input {
 | 
				
			||||||
  const ALLOW_EMPTY = false;
 | 
					  const ALLOW_EMPTY = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function formAccess($key): IAccess {
 | 
					  function __construct(&$dest=null, ?array $params=null) {
 | 
				
			||||||
    return new FormAccess($key, [
 | 
					    parent::__construct($dest, $params);
 | 
				
			||||||
      "allow_empty" => $this->allowEmpty,
 | 
					    $this->access = new ShadowAccess($this->formAccess($this->access), $this->access);
 | 
				
			||||||
    ]);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected function access($key): IAccess {
 | 
					  protected function formAccess(IAccess $access): IAccess {
 | 
				
			||||||
    return $this->keyAccess[$key] ??= new ShadowAccess($this->formAccess($key), new KeyAccess($this->value, $key, [
 | 
					    return new FormAccess(null, [
 | 
				
			||||||
      "allow_empty" => $this->allowEmpty,
 | 
					      "allow_empty" => $access->isAllowEmpty(),
 | 
				
			||||||
    ]));
 | 
					    ]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\input;
 | 
					namespace nulib\schema\input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\php\access\GetAccess;
 | 
					use nulib\php\access\GetAccess;
 | 
				
			||||||
use nur\sery\wip\php\access\IAccess;
 | 
					use nulib\php\access\IAccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class GetInput: accès à des paramètres de formulaire de type GET uniquement
 | 
					 * Class GetInput: accès à des paramètres de formulaire de type GET uniquement
 | 
				
			||||||
@ -11,9 +11,9 @@ use nur\sery\wip\php\access\IAccess;
 | 
				
			|||||||
 * une référence
 | 
					 * une référence
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class GetInput extends FormInput {
 | 
					class GetInput extends FormInput {
 | 
				
			||||||
  protected function formAccess($key): IAccess {
 | 
					  protected function formAccess(IAccess $access): IAccess {
 | 
				
			||||||
    return new GetAccess($key, [
 | 
					    return new GetAccess(null, [
 | 
				
			||||||
      "allow_empty" => $this->allowEmpty,
 | 
					      "allow_empty" => $access->isAllowEmpty(),
 | 
				
			||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,11 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\input;
 | 
					namespace nulib\schema\input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\php\access\IAccess;
 | 
					use nulib\php\access\IAccess;
 | 
				
			||||||
use nur\sery\wip\php\access\KeyAccess;
 | 
					use nulib\php\access\KeyAccess;
 | 
				
			||||||
use nur\sery\wip\php\access\ValueAccess;
 | 
					use nulib\php\access\PropertyAccess;
 | 
				
			||||||
 | 
					use nulib\ref\schema\ref_input;
 | 
				
			||||||
 | 
					use nulib\StateException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class Input: accès à une valeur
 | 
					 * Class Input: accès à une valeur
 | 
				
			||||||
@ -13,54 +15,76 @@ use nur\sery\wip\php\access\ValueAccess;
 | 
				
			|||||||
class Input {
 | 
					class Input {
 | 
				
			||||||
  const ALLOW_EMPTY = true;
 | 
					  const ALLOW_EMPTY = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function __construct(&$value=null, ?array $params=null) {
 | 
					  private static function unexpected_access_type(): StateException {
 | 
				
			||||||
    $this->value =& $value;
 | 
					    return StateException::unexpected_state("access_type");
 | 
				
			||||||
    $this->allowEmpty = $params["allow_empty"] ?? static::ALLOW_EMPTY;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @var mixed */
 | 
					  function __construct(&$dest=null, ?array $params=null) {
 | 
				
			||||||
  protected $value;
 | 
					    $accessType = $params["access_type"] ?? ref_input::ACCESS_AUTO;
 | 
				
			||||||
 | 
					    if ($accessType === ref_input::ACCESS_AUTO) {
 | 
				
			||||||
 | 
					      $accessType = is_object($dest)? ref_input::ACCESS_PROPERTY : ref_input::ACCESS_KEY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					    $allowEmpty = $params["allow_empty"] ?? static::ALLOW_EMPTY;
 | 
				
			||||||
   * @var bool comment considérer une chaine vide: "" si allowEmpty, null sinon
 | 
					    if ($accessType == ref_input::ACCESS_PROPERTY) {
 | 
				
			||||||
   */
 | 
					      $this->access = new PropertyAccess($dest, null, [
 | 
				
			||||||
  protected $allowEmpty;
 | 
					        "allow_empty" => $allowEmpty,
 | 
				
			||||||
 | 
					        "allow_null" => true,
 | 
				
			||||||
  protected ?ValueAccess $valueAccess = null;
 | 
					      ]);
 | 
				
			||||||
  protected ?array $keyAccess = null;
 | 
					    } elseif ($accessType == ref_input::ACCESS_KEY) {
 | 
				
			||||||
 | 
					      $this->access = new KeyAccess($dest, null, [
 | 
				
			||||||
  protected function access($key): IAccess {
 | 
					        "allow_empty" => $allowEmpty,
 | 
				
			||||||
    if ($key === null) {
 | 
					 | 
				
			||||||
      return $this->valueAccess ??= new ValueAccess($this->value, [
 | 
					 | 
				
			||||||
        "allow_null" => true,
 | 
					        "allow_null" => true,
 | 
				
			||||||
        "allow_empty" => $this->allowEmpty,
 | 
					 | 
				
			||||||
      ]);
 | 
					      ]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return $this->keyAccess[$key] ??= new KeyAccess($this->value, $key, [
 | 
					      throw self::unexpected_access_type();
 | 
				
			||||||
        "allow_empty" => $this->allowEmpty,
 | 
					 | 
				
			||||||
      ]);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected IAccess $access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** tester si la valeur existe sans tenir compte de $allowEmpty */
 | 
					  /** tester si la valeur existe sans tenir compte de $allowEmpty */
 | 
				
			||||||
  function isPresent($key=null): bool {
 | 
					  function isPresent($key=null): bool {
 | 
				
			||||||
    return $this->access($key)->exists();
 | 
					    return $this->access->resetKey($key)->exists();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** tester si la valeur est disponible en tenant compte de $allowEmpty */
 | 
					  /** tester si la valeur est disponible en tenant compte de $allowEmpty */
 | 
				
			||||||
  function isAvailable($key=null): bool {
 | 
					  function isAvailable($key=null): bool {
 | 
				
			||||||
    return $this->access($key)->available();
 | 
					    return $this->access->resetKey($key)->available();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get($key=null) {
 | 
					  function get($key=null) {
 | 
				
			||||||
    return $this->access($key)->get();
 | 
					    return $this->access->resetKey($key)->get();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function set($value, $key=null): void {
 | 
					  function set($value, $key=null): void {
 | 
				
			||||||
    $this->access($key)->set($value);
 | 
					    $this->access->resetKey($key)->set($value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function unset($key=null): void {
 | 
					  function unset($key=null): void {
 | 
				
			||||||
    $this->access($key)->del();
 | 
					    $this->access->resetKey($key)->del();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addKey($key): Input {
 | 
				
			||||||
 | 
					    if ($key === null) return $this;
 | 
				
			||||||
 | 
					    $input = clone $this;
 | 
				
			||||||
 | 
					    $input->access = $this->access->addKey($key);
 | 
				
			||||||
 | 
					    return $input;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureAssoc(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $this->access->ensureAssoc($keys, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $this->access->ensureKeys($defaults, $missings, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function deleteMissings(array $missings, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $this->access->deleteMissings($missings, $params);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureOrder(array $keys, ?array $params=null): void {
 | 
				
			||||||
 | 
					    $this->access->ensureOrder($keys, $params);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\input;
 | 
					namespace nulib\schema\input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\php\access\IAccess;
 | 
					use nulib\php\access\IAccess;
 | 
				
			||||||
use nur\sery\wip\php\access\PostAccess;
 | 
					use nulib\php\access\PostAccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class PostInput: accès à des paramètres de formulaire de type POST uniquement
 | 
					 * Class PostInput: accès à des paramètres de formulaire de type POST uniquement
 | 
				
			||||||
@ -11,9 +11,9 @@ use nur\sery\wip\php\access\PostAccess;
 | 
				
			|||||||
 * une référence
 | 
					 * une référence
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class PostInput extends FormInput {
 | 
					class PostInput extends FormInput {
 | 
				
			||||||
  protected function formAccess($key): IAccess {
 | 
					  protected function formAccess(IAccess $access): IAccess {
 | 
				
			||||||
    return new PostAccess($key, [
 | 
					    return new PostAccess(null, [
 | 
				
			||||||
      "allow_empty" => $this->allowEmpty,
 | 
					      "allow_empty" => $access->isAllowEmpty(),
 | 
				
			||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,22 +1,22 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema;
 | 
					namespace nulib\schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\schema\types\IType;
 | 
				
			||||||
 | 
					use nulib\schema\types\Registry;
 | 
				
			||||||
 | 
					use nulib\schema\types\tarray;
 | 
				
			||||||
 | 
					use nulib\schema\types\tbool;
 | 
				
			||||||
 | 
					use nulib\schema\types\tcontent;
 | 
				
			||||||
 | 
					use nulib\schema\types\tfloat;
 | 
				
			||||||
 | 
					use nulib\schema\types\tfunc;
 | 
				
			||||||
 | 
					use nulib\schema\types\tint;
 | 
				
			||||||
 | 
					use nulib\schema\types\tkey;
 | 
				
			||||||
 | 
					use nulib\schema\types\tmixed;
 | 
				
			||||||
 | 
					use nulib\schema\types\tpkey;
 | 
				
			||||||
 | 
					use nulib\schema\types\traw;
 | 
				
			||||||
 | 
					use nulib\schema\types\trawstring;
 | 
				
			||||||
 | 
					use nulib\schema\types\tstring;
 | 
				
			||||||
 | 
					use nulib\schema\types\ttext;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\sery\wip\schema\types\IType;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\Registry;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tarray;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tbool;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tcallable;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tcontent;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tfloat;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tint;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tkey;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tmixed;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tpkey;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\traw;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\trawstring;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\tstring;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\types\ttext;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class types: classe outil pour gérer le registre de types
 | 
					 * Class types: classe outil pour gérer le registre de types
 | 
				
			||||||
@ -47,7 +47,7 @@ class types {
 | 
				
			|||||||
  static function int(bool $nullable=true): tint { return self::get($nullable, "int"); }
 | 
					  static function int(bool $nullable=true): tint { return self::get($nullable, "int"); }
 | 
				
			||||||
  static function float(bool $nullable=true): tfloat { return self::get($nullable, "float"); }
 | 
					  static function float(bool $nullable=true): tfloat { return self::get($nullable, "float"); }
 | 
				
			||||||
  static function array(bool $nullable=true): tarray { return self::get($nullable, "array"); }
 | 
					  static function array(bool $nullable=true): tarray { return self::get($nullable, "array"); }
 | 
				
			||||||
  static function callable(bool $nullable=true): tcallable { return self::get($nullable, "callable"); }
 | 
					  static function callable(bool $nullable=true): tfunc { return self::get($nullable, "callable"); }
 | 
				
			||||||
  static function raw(bool $nullable=true): traw { return self::get($nullable, "raw"); }
 | 
					  static function raw(bool $nullable=true): traw { return self::get($nullable, "raw"); }
 | 
				
			||||||
  static function mixed(bool $nullable=true): tmixed { return self::get($nullable, "mixed"); }
 | 
					  static function mixed(bool $nullable=true): tmixed { return self::get($nullable, "mixed"); }
 | 
				
			||||||
  static function key(bool $nullable=true): tkey { return self::get($nullable, "key"); }
 | 
					  static function key(bool $nullable=true): tkey { return self::get($nullable, "key"); }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Interface IType: un type de données
 | 
					 * Interface IType: un type de données
 | 
				
			||||||
@ -23,7 +23,7 @@ interface IType {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @return string la classe des objets gérés par ce format: le type attendu
 | 
					   * @return string la classe des objets gérés par ce format: le type attendu
 | 
				
			||||||
   * par {@link format()} et le type retourné par {@link verifix()}
 | 
					   * par {@link format()} et le type retourné par {@link normalize()}
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * Les valeurs "mixed", "bool", "float", "int", "string" et "array" peuvent
 | 
					   * Les valeurs "mixed", "bool", "float", "int", "string" et "array" peuvent
 | 
				
			||||||
   * aussi être retournées, bien qu'elles ne soient pas à proprement parler des
 | 
					   * aussi être retournées, bien qu'elles ne soient pas à proprement parler des
 | 
				
			||||||
@ -48,26 +48,25 @@ interface IType {
 | 
				
			|||||||
  function getPhpType(bool $allowNullable=true): ?string;
 | 
					  function getPhpType(bool $allowNullable=true): ?string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * indiquer si c'est le type d'une valeur qui ne peut prendre que 2 états: une
 | 
					   * obtenir la valeur "inexistante" pour les objets de ce type
 | 
				
			||||||
   * "vraie" et une "fausse"
 | 
					   *
 | 
				
			||||||
 | 
					   * si $valid reçoit la valeur false, il faut ignorer la valeur de retour:
 | 
				
			||||||
 | 
					   * cela veut dire qu'il n'y a pas de valeur "inexistant" pour les valeurs de
 | 
				
			||||||
 | 
					   * ce type
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function is2States(): bool;
 | 
					  function getMissingValue(?bool &$valid=null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** obtenir la valeur "nulle" pour les objets de ce type */
 | 
				
			||||||
 | 
					  function getNullValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * Si {@link is2States()} est vrai, retourner les deux valeurs [faux, vrai]
 | 
					   * si c'est le type d'une valeur qui ne prendre qu'une liste prédéterminée
 | 
				
			||||||
 | 
					   * d'états spécifiques, retourner le nombre d'états possibles, et mettre à
 | 
				
			||||||
 | 
					   * jour $states avec les valeurs possibles
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * sinon, retourner 0 et ne pas mettre $states à jour
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function get2States(): array;
 | 
					  function getNbStates(?array &$states=null): int;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * indiquer si c'est le type d'une valeur qui ne peut prendre que 3 états: une
 | 
					 | 
				
			||||||
   * "vraie", une "fausse", et une "indéterminée"
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  function is3States(): bool;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * Si {@link is3States()} est vrai, retourner les 3 valeurs [faux, vrai, undef]
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  function get3States(): array;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** la donnée $input($valueKey) est-elle disponible? */
 | 
					  /** la donnée $input($valueKey) est-elle disponible? */
 | 
				
			||||||
  function isAvailable(Input $input, $valueKey): bool;
 | 
					  function isAvailable(Input $input, $valueKey): bool;
 | 
				
			||||||
@ -98,15 +97,18 @@ interface IType {
 | 
				
			|||||||
  function parse(string $value);
 | 
					  function parse(string $value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * analyser, corriger éventuellement et normaliser la valeur
 | 
					   * normaliser la valeur. elle *doit* déjà être valide.
 | 
				
			||||||
   *
 | 
					   * Si $value est un string. elle *doit* avoir déjà été traitée au préalable
 | 
				
			||||||
   * NB: si $value est un string. elle doit avoir déjà été traitée au préalable
 | 
					 | 
				
			||||||
   * par extract() et parse()
 | 
					   * par extract() et parse()
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * si la valeur était déjà normalisée, ou si une erreur s'est produite,
 | 
					   * - si $result indique que la valeur est déjà normalisée, cette méthode ne
 | 
				
			||||||
   * retourner false.
 | 
					   * fait rien
 | 
				
			||||||
 | 
					   * - si la valeur était déjà normalisée, mettre à jour $result pour indiquer
 | 
				
			||||||
 | 
					   * que la valeur est normalisée et retourner false
 | 
				
			||||||
 | 
					   * - sinon, retourner true pour indiquer qu'il a fallut normaliser la valeur.
 | 
				
			||||||
 | 
					   * $result n'est pas modifié
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool;
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * formatter la valeur pour affichage. si $value n'est pas null, elle est
 | 
					   * formatter la valeur pour affichage. si $value n'est pas null, elle est
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
use nulib\php\func;
 | 
					use nulib\php\func;
 | 
				
			||||||
@ -12,10 +12,9 @@ class Registry {
 | 
				
			|||||||
    "text" => ttext::class,
 | 
					    "text" => ttext::class,
 | 
				
			||||||
    "bool" => tbool::class, "boolean" => tbool::class,
 | 
					    "bool" => tbool::class, "boolean" => tbool::class,
 | 
				
			||||||
    "int" => tint::class, "integer" => tint::class,
 | 
					    "int" => tint::class, "integer" => tint::class,
 | 
				
			||||||
    "float" => tfloat::class, "flt" => tfloat::class,
 | 
					    "float" => tfloat::class, "flt" => tfloat::class, "double" => tfloat::class, "dbl" => tfloat::class,
 | 
				
			||||||
    "double" => tfloat::class, "dbl" => tfloat::class,
 | 
					 | 
				
			||||||
    "array" => tarray::class,
 | 
					    "array" => tarray::class,
 | 
				
			||||||
    "callable" => tcallable::class,
 | 
					    "func" => tfunc::class, "function" => tfunc::class, "callable" => tfunc::class,
 | 
				
			||||||
    # types spéciaux
 | 
					    # types spéciaux
 | 
				
			||||||
    "raw" => traw::class,
 | 
					    "raw" => traw::class,
 | 
				
			||||||
    "mixed" => tmixed::class,
 | 
					    "mixed" => tmixed::class,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class _tformatable extends _tsimple {
 | 
					abstract class _tformatable extends _tsimple {
 | 
				
			||||||
  const FORMAT = null;
 | 
					  const FORMAT = null;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\StateException;
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
use nur\prop;
 | 
					use nur\prop;
 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					 | 
				
			||||||
use nur\str;
 | 
					use nur\str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class _tsimple implements IType {
 | 
					abstract class _tsimple implements IType {
 | 
				
			||||||
@ -43,20 +42,13 @@ abstract class _tsimple implements IType {
 | 
				
			|||||||
    return $phpType;
 | 
					    return $phpType;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function is2States(): bool {
 | 
					  function getMissingValue(?bool &$valid=null) {
 | 
				
			||||||
 | 
					    $valid = true;
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get2States(): array {
 | 
					  function getNbStates(?array &$states=null): int {
 | 
				
			||||||
    throw StateException::not_implemented();
 | 
					    return 0;
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function is3States(): bool {
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function get3States(): array {
 | 
					 | 
				
			||||||
    throw StateException::not_implemented();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAvailable(Input $input, $valueKey): bool {
 | 
					  function isAvailable(Input $input, $valueKey): bool {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\str;
 | 
					use nulib\str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class _tunion extends _tsimple {
 | 
					abstract class _tunion extends _tsimple {
 | 
				
			||||||
  function getPhpType(bool $allowNullable=true): ?string {
 | 
					  function getPhpType(bool $allowNullable=true): ?string {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					use nulib\schema\Result;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tarray extends _tstring {
 | 
					class tarray extends _tstring {
 | 
				
			||||||
  const NAME = "array";
 | 
					  const NAME = "array";
 | 
				
			||||||
@ -35,9 +33,13 @@ class tarray extends _tstring {
 | 
				
			|||||||
    return "array";
 | 
					    return "array";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return $this->nullable? null: [];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
    $normalized = is_array($value);
 | 
					    $normalized = is_array($value);
 | 
				
			||||||
    return is_scalar($value) || is_array($value);
 | 
					    return $normalized || is_scalar($value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function parse(string $value) {
 | 
					  function parse(string $value) {
 | 
				
			||||||
@ -46,26 +48,16 @@ class tarray extends _tstring {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_array($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_array($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_string($value)) {
 | 
					 | 
				
			||||||
      try {
 | 
					 | 
				
			||||||
        $value = $this->parse($value);
 | 
					 | 
				
			||||||
        $result->setValid();
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      } catch (ValueException $e) {
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = cl::with($value);
 | 
					      $value = cl::with($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,13 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\prop;
 | 
					use nur\prop;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tbool extends _tformatable {
 | 
					class tbool extends _tformatable {
 | 
				
			||||||
  const NAME = "bool";
 | 
					  const NAME = "bool";
 | 
				
			||||||
@ -60,20 +59,23 @@ class tbool extends _tformatable {
 | 
				
			|||||||
    return "bool";
 | 
					    return "bool";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function is2States(): bool {
 | 
					  function getMissingValue(?bool &$valid=null) {
 | 
				
			||||||
    return !$this->nullable;
 | 
					    $valid = false;
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function get2States(): array {
 | 
					  function getNullValue() {
 | 
				
			||||||
    return [false, true];
 | 
					    return $this->nullable? null: false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function is3States(): bool {
 | 
					  public function getNbStates(?array &$states=null): int {
 | 
				
			||||||
    return $this->nullable;
 | 
					    if ($this->nullable) {
 | 
				
			||||||
  }
 | 
					      $states = [false, true, null];
 | 
				
			||||||
 | 
					      return 3;
 | 
				
			||||||
  function get3States(): array {
 | 
					    } else {
 | 
				
			||||||
    return [false, true, null];
 | 
					      $states = [false, true];
 | 
				
			||||||
 | 
					      return 2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAvailable(Input $input, $valueKey): bool {
 | 
					  function isAvailable(Input $input, $valueKey): bool {
 | 
				
			||||||
@ -96,26 +98,16 @@ class tbool extends _tformatable {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_bool($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_bool($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_string($value)) {
 | 
					 | 
				
			||||||
      try {
 | 
					 | 
				
			||||||
        $value = $this->parse($value);
 | 
					 | 
				
			||||||
        $result->setValid();
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      } catch (ValueException $e) {
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = boolval($value);
 | 
					      $value = boolval($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,68 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Exception;
 | 
					 | 
				
			||||||
use nulib\php\func;
 | 
					 | 
				
			||||||
use nulib\ValueException;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class tcallable extends _tsimple {
 | 
					 | 
				
			||||||
  const NAME = "callable";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const ALIASES = ["func", "function"];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static function ensure_callable(&$callable): void {
 | 
					 | 
				
			||||||
    $callable = func::ensure($callable);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static function ensure_ncallable(&$callable): void {
 | 
					 | 
				
			||||||
    if ($callable !== null) self::ensure_callable($callable);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function getClass(): string {
 | 
					 | 
				
			||||||
    return func::class;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					 | 
				
			||||||
    $normalized = is_callable($value);
 | 
					 | 
				
			||||||
    return func::check($value);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function parse(string $value) {
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      return func::ensure($value);
 | 
					 | 
				
			||||||
    } catch (Exception $e) {
 | 
					 | 
				
			||||||
      throw new ValueException(null, null, 0, $e);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					 | 
				
			||||||
    if ($value instanceof func) {
 | 
					 | 
				
			||||||
      $result->setNormalized();
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_callable($value)) {
 | 
					 | 
				
			||||||
      $value = func::with($value);
 | 
					 | 
				
			||||||
      $result->setNormalized();
 | 
					 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    } elseif (is_string($value)) {
 | 
					 | 
				
			||||||
      try {
 | 
					 | 
				
			||||||
        $value = $this->parse($value);
 | 
					 | 
				
			||||||
        $result->setValid();
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      } catch (ValueException $e) {
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function format($value, $format=null): string {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,11 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\php\content\c;
 | 
					use nulib\php\content\c;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					use nulib\schema\Result;
 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class tcontent extends _tunion {
 | 
					abstract class tcontent extends _tunion {
 | 
				
			||||||
  const NAME = "content";
 | 
					  const NAME = "content";
 | 
				
			||||||
@ -23,9 +22,13 @@ abstract class tcontent extends _tunion {
 | 
				
			|||||||
    return "string|array";
 | 
					    return "string|array";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return $this->nullable? null: [];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
    $normalized = is_string($value) || is_array($value);
 | 
					    $normalized = is_string($value) || is_array($value);
 | 
				
			||||||
    return is_scalar($value) || is_array($value);
 | 
					    return $normalized || is_scalar($value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function parse(string $value) {
 | 
					  function parse(string $value) {
 | 
				
			||||||
@ -33,21 +36,17 @@ abstract class tcontent extends _tunion {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_string($value) || is_array($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_string($value) || is_array($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = strval($value);
 | 
					      $value = strval($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function format($value, $format=null): string {
 | 
					  function format($value, $format=null): string {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tfloat extends _tformatable {
 | 
					class tfloat extends _tformatable {
 | 
				
			||||||
  const NAME = "float";
 | 
					  const NAME = "float";
 | 
				
			||||||
@ -24,6 +23,10 @@ class tfloat extends _tformatable {
 | 
				
			|||||||
    return "float";
 | 
					    return "float";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return $this->nullable? null: 0.0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
    $normalized = is_float($value);
 | 
					    $normalized = is_float($value);
 | 
				
			||||||
    return is_scalar($value);
 | 
					    return is_scalar($value);
 | 
				
			||||||
@ -40,26 +43,16 @@ class tfloat extends _tformatable {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_float($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_float($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_string($value)) {
 | 
					 | 
				
			||||||
      try {
 | 
					 | 
				
			||||||
        $value = $this->parse($value);
 | 
					 | 
				
			||||||
        $result->setValid();
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      } catch (ValueException $e) {
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = floatval($value);
 | 
					      $value = floatval($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										61
									
								
								src/schema/types/tfunc.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/schema/types/tfunc.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use nulib\php\func;
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class tfunc extends _tsimple {
 | 
				
			||||||
 | 
					  const NAME = "func";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const ALIASES = ["function", "callable"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static function ensure_func(&$func): void {
 | 
				
			||||||
 | 
					    $func = func::ensure($func);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static function ensure_nfunc(&$func): void {
 | 
				
			||||||
 | 
					    if ($func !== null) self::ensure_func($func);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getClass(): string {
 | 
				
			||||||
 | 
					    return func::class;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
 | 
					    $normalized = $value instanceof func;
 | 
				
			||||||
 | 
					    return func::check($value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function parse(string $value) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      return func::ensure($value);
 | 
				
			||||||
 | 
					    } catch (Exception $e) {
 | 
				
			||||||
 | 
					      throw new ValueException(null, null, 0, $e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif ($value instanceof func) {
 | 
				
			||||||
 | 
					      $result->setNormalized();
 | 
				
			||||||
 | 
					    } elseif (is_callable($value)) {
 | 
				
			||||||
 | 
					      $value = func::with($value);
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function format($value, $format=null): string {
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,12 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tgeneric extends _tsimple {
 | 
					class tgeneric extends _tsimple {
 | 
				
			||||||
  function __construct(string $class, bool $nullable, ?array $params=null) {
 | 
					  function __construct(string $class, bool $nullable, ?array $params=null) {
 | 
				
			||||||
@ -20,8 +18,8 @@ class tgeneric extends _tsimple {
 | 
				
			|||||||
    return $this->class;
 | 
					    return $this->class;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAvailable(Input $input, $valueKey): bool {
 | 
					  function getNullValue() {
 | 
				
			||||||
    return $input->isAvailable($valueKey);
 | 
					    return null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public function isNull($value): bool {
 | 
					  public function isNull($value): bool {
 | 
				
			||||||
@ -29,8 +27,8 @@ class tgeneric extends _tsimple {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
    $normalized = true;
 | 
					    $normalized = $value instanceof $this->class;
 | 
				
			||||||
    return $value instanceof $this->class;
 | 
					    return $normalized;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function parse(string $value) {
 | 
					  function parse(string $value) {
 | 
				
			||||||
@ -38,11 +36,10 @@ class tgeneric extends _tsimple {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    $result->setNormalized();
 | 
					    if (!$result->normalized) $result->setNormalized();
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nulib\ValueException;
 | 
					use nulib\ValueException;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tint extends _tformatable {
 | 
					class tint extends _tformatable {
 | 
				
			||||||
  const NAME = "int";
 | 
					  const NAME = "int";
 | 
				
			||||||
@ -26,6 +25,10 @@ class tint extends _tformatable {
 | 
				
			|||||||
    return "int";
 | 
					    return "int";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return $this->nullable? null: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
    $normalized = is_int($value);
 | 
					    $normalized = is_int($value);
 | 
				
			||||||
    return is_scalar($value);
 | 
					    return is_scalar($value);
 | 
				
			||||||
@ -42,26 +45,16 @@ class tint extends _tformatable {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_int($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_int($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_string($value)) {
 | 
					 | 
				
			||||||
      try {
 | 
					 | 
				
			||||||
        $value = $this->parse($value);
 | 
					 | 
				
			||||||
        $result->setValid();
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      } catch (ValueException $e) {
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = intval($value);
 | 
					      $value = intval($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,9 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					use nulib\schema\Result;
 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tkey extends _tunion {
 | 
					class tkey extends _tunion {
 | 
				
			||||||
  const NAME = "key";
 | 
					  const NAME = "key";
 | 
				
			||||||
@ -23,9 +22,13 @@ class tkey extends _tunion {
 | 
				
			|||||||
    return "string|int";
 | 
					    return "string|int";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return $this->nullable? null: "";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
    $normalized = is_string($value) || is_int($value);
 | 
					    $normalized = is_string($value) || is_int($value);
 | 
				
			||||||
    return is_scalar($value);
 | 
					    return $normalized || is_scalar($value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function parse(string $value) {
 | 
					  function parse(string $value) {
 | 
				
			||||||
@ -33,21 +36,17 @@ class tkey extends _tunion {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_string($value) || is_int($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_string($value) || is_int($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = strval($value);
 | 
					      $value = strval($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function format($value, $format=null): string {
 | 
					  function format($value, $format=null): string {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					use nulib\schema\Result;
 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tmixed extends _tsimple {
 | 
					class tmixed extends _tsimple {
 | 
				
			||||||
  const NAME = "mixed";
 | 
					  const NAME = "mixed";
 | 
				
			||||||
@ -14,6 +13,15 @@ class tmixed extends _tsimple {
 | 
				
			|||||||
    return "mixed";
 | 
					    return "mixed";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getMissingValue(?bool &$valid=null) {
 | 
				
			||||||
 | 
					    $valid = false;
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isAvailable(Input $input, $valueKey): bool {
 | 
					  function isAvailable(Input $input, $valueKey): bool {
 | 
				
			||||||
    return $input->isAvailable($valueKey);
 | 
					    return $input->isAvailable($valueKey);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -32,11 +40,10 @@ class tmixed extends _tsimple {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    $result->setNormalized();
 | 
					    if (!$result->normalized) $result->setNormalized();
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,9 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					use nulib\schema\Result;
 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tpkey extends _tunion {
 | 
					class tpkey extends _tunion {
 | 
				
			||||||
  const NAME = "pkey";
 | 
					  const NAME = "pkey";
 | 
				
			||||||
@ -28,9 +27,13 @@ class tpkey extends _tunion {
 | 
				
			|||||||
    return "string|int|array";
 | 
					    return "string|int|array";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return $this->nullable? null: [];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isValid($value, ?bool &$normalized=null): bool {
 | 
					  function isValid($value, ?bool &$normalized=null): bool {
 | 
				
			||||||
    $normalized = is_string($value) || is_int($value) || is_array($value);
 | 
					    $normalized = is_string($value) || is_int($value) || is_array($value);
 | 
				
			||||||
    return is_scalar($value) || is_array($value);
 | 
					    return $normalized || is_scalar($value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function parse(string $value) {
 | 
					  function parse(string $value) {
 | 
				
			||||||
@ -38,21 +41,17 @@ class tpkey extends _tunion {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_string($value) || is_int($value) || is_array($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_string($value) || is_int($value) || is_array($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = strval($value);
 | 
					      $value = strval($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function format($value, $format=null): string {
 | 
					  function format($value, $format=null): string {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\sery\wip\schema\input\Input;
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class traw extends tmixed {
 | 
					class traw extends tmixed {
 | 
				
			||||||
  const NAME = "raw";
 | 
					  const NAME = "raw";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarSchema;
 | 
				
			||||||
 | 
					use nulib\schema\Result;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
use nulib\str;
 | 
					use nulib\str;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarResult;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarSchema;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Result;
 | 
					 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class trawstring extends _tstring {
 | 
					class trawstring extends _tstring {
 | 
				
			||||||
  const NAME = "rawstring";
 | 
					  const NAME = "rawstring";
 | 
				
			||||||
@ -24,6 +23,10 @@ class trawstring extends _tstring {
 | 
				
			|||||||
    return "string";
 | 
					    return "string";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getNullValue() {
 | 
				
			||||||
 | 
					    return $this->nullable? null: "";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function isNull($value): bool {
 | 
					  function isNull($value): bool {
 | 
				
			||||||
    return $value === null;
 | 
					    return $value === null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -41,21 +44,17 @@ class trawstring extends _tstring {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @var ScalarResult $result
 | 
					 | 
				
			||||||
   * @var ScalarSchema $schema
 | 
					   * @var ScalarSchema $schema
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function verifix(&$value, Result $result, Schema $schema): bool {
 | 
					  function normalize(&$value, Result $result, Schema $schema): bool {
 | 
				
			||||||
    if (is_string($value)) {
 | 
					    if ($result->normalized) {
 | 
				
			||||||
 | 
					    } elseif (is_string($value)) {
 | 
				
			||||||
      $result->setNormalized();
 | 
					      $result->setNormalized();
 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    } elseif (is_scalar($value)) {
 | 
					    } elseif (is_scalar($value)) {
 | 
				
			||||||
      $value = strval($value);
 | 
					      $value = strval($value);
 | 
				
			||||||
      $result->setValid();
 | 
					 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      $result->setInvalid($value, $schema);
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function format($value, $format=null): string {
 | 
					  function format($value, $format=null): string {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tstring extends trawstring {
 | 
					class tstring extends trawstring {
 | 
				
			||||||
  const NAME = "string";
 | 
					  const NAME = "string";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ttext extends trawstring {
 | 
					class ttext extends trawstring {
 | 
				
			||||||
  const NAME = "text";
 | 
					  const NAME = "text";
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								src/tools/Json2yamlApp.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/tools/Json2yamlApp.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\tools;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\app\cli\Application;
 | 
				
			||||||
 | 
					use nulib\ext\json;
 | 
				
			||||||
 | 
					use nulib\ext\yaml;
 | 
				
			||||||
 | 
					use nulib\os\path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Json2yamlApp extends Application {
 | 
				
			||||||
 | 
					  private $args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function main() {
 | 
				
			||||||
 | 
					    $input = $this->args[0] ?? null;
 | 
				
			||||||
 | 
					    if ($input === null || $input === "-") {
 | 
				
			||||||
 | 
					      $output = null;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $output = path::ensure_ext($input, ".yml", ".json");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $data = json::load($input);
 | 
				
			||||||
 | 
					    yaml::dump($data, $output);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/tools/Yaml2jsonApp.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/tools/Yaml2jsonApp.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\tools;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\app\cli\Application;
 | 
				
			||||||
 | 
					use nulib\ext\json;
 | 
				
			||||||
 | 
					use nulib\ext\yaml;
 | 
				
			||||||
 | 
					use nulib\os\path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Yaml2jsonApp extends Application {
 | 
				
			||||||
 | 
					  private $args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function main() {
 | 
				
			||||||
 | 
					    $input = $this->args[0] ?? null;
 | 
				
			||||||
 | 
					    if ($input === null || $input === "-") {
 | 
				
			||||||
 | 
					      $output = null;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $output = path::ensure_ext($input, ".json", [".yml", ".yaml"]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $data = yaml::load($input);
 | 
				
			||||||
 | 
					    json::dump($data, $output);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\web\content;
 | 
					namespace nulib\web\content;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\A;
 | 
					use nulib\A;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\web\content;
 | 
					namespace nulib\web\content;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class v: classe outil pour gérer du contenu pour le web
 | 
					 * Class v: classe outil pour gérer du contenu pour le web
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nulib;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class app extends \nur\sery\app {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
namespace nulib\app\cli;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class Application extends \nur\sery\app\cli\Application {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										132
									
								
								tests/appTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								tests/appTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib {
 | 
				
			||||||
 | 
					  use nulib\tests\TestCase;
 | 
				
			||||||
 | 
					  use nulib\impl\config;
 | 
				
			||||||
 | 
					  use nulib\impl\myapp;
 | 
				
			||||||
 | 
					  use nulib\impl\MyApplication1;
 | 
				
			||||||
 | 
					  use nulib\impl\MyApplication2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  class appTest extends TestCase {
 | 
				
			||||||
 | 
					    function testWith() {
 | 
				
			||||||
 | 
					      $projdir = config::get_projdir();
 | 
				
			||||||
 | 
					      $cwd = getcwd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      myapp::reset();
 | 
				
			||||||
 | 
					      $app1 = myapp::with(MyApplication1::class);
 | 
				
			||||||
 | 
					      self::assertSame([
 | 
				
			||||||
 | 
					        "projdir" => $projdir,
 | 
				
			||||||
 | 
					        "vendor" => [
 | 
				
			||||||
 | 
					          "bindir" => "$projdir/vendor/bin",
 | 
				
			||||||
 | 
					          "autoload" => "$projdir/vendor/autoload.php",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "appcode" => "nur-sery",
 | 
				
			||||||
 | 
					        "cwd" => $cwd,
 | 
				
			||||||
 | 
					        "datadir" => "$projdir/devel",
 | 
				
			||||||
 | 
					        "etcdir" => "$projdir/devel/etc",
 | 
				
			||||||
 | 
					        "vardir" => "$projdir/devel/var",
 | 
				
			||||||
 | 
					        "logdir" => "$projdir/devel/log",
 | 
				
			||||||
 | 
					        "profile" => "devel",
 | 
				
			||||||
 | 
					        "appgroup" => null,
 | 
				
			||||||
 | 
					        "name" => "my-application1",
 | 
				
			||||||
 | 
					        "title" => null,
 | 
				
			||||||
 | 
					      ], $app1->getParams());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      $app2 = myapp::with(MyApplication2::class, $app1);
 | 
				
			||||||
 | 
					      self::assertSame([
 | 
				
			||||||
 | 
					        "projdir" => $projdir,
 | 
				
			||||||
 | 
					        "vendor" => [
 | 
				
			||||||
 | 
					          "bindir" => "$projdir/vendor/bin",
 | 
				
			||||||
 | 
					          "autoload" => "$projdir/vendor/autoload.php",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "appcode" => "nur-sery",
 | 
				
			||||||
 | 
					        "cwd" => $cwd,
 | 
				
			||||||
 | 
					        "datadir" => "$projdir/devel",
 | 
				
			||||||
 | 
					        "etcdir" => "$projdir/devel/etc",
 | 
				
			||||||
 | 
					        "vardir" => "$projdir/devel/var",
 | 
				
			||||||
 | 
					        "logdir" => "$projdir/devel/log",
 | 
				
			||||||
 | 
					        "profile" => "devel",
 | 
				
			||||||
 | 
					        "appgroup" => null,
 | 
				
			||||||
 | 
					        "name" => "my-application2",
 | 
				
			||||||
 | 
					        "title" => null,
 | 
				
			||||||
 | 
					      ], $app2->getParams());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function testInit() {
 | 
				
			||||||
 | 
					      $projdir = config::get_projdir();
 | 
				
			||||||
 | 
					      $cwd = getcwd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      myapp::reset();
 | 
				
			||||||
 | 
					      myapp::init(MyApplication1::class);
 | 
				
			||||||
 | 
					      self::assertSame([
 | 
				
			||||||
 | 
					        "projdir" => $projdir,
 | 
				
			||||||
 | 
					        "vendor" => [
 | 
				
			||||||
 | 
					          "bindir" => "$projdir/vendor/bin",
 | 
				
			||||||
 | 
					          "autoload" => "$projdir/vendor/autoload.php",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "appcode" => "nur-sery",
 | 
				
			||||||
 | 
					        "cwd" => $cwd,
 | 
				
			||||||
 | 
					        "datadir" => "$projdir/devel",
 | 
				
			||||||
 | 
					        "etcdir" => "$projdir/devel/etc",
 | 
				
			||||||
 | 
					        "vardir" => "$projdir/devel/var",
 | 
				
			||||||
 | 
					        "logdir" => "$projdir/devel/log",
 | 
				
			||||||
 | 
					        "profile" => "devel",
 | 
				
			||||||
 | 
					        "appgroup" => null,
 | 
				
			||||||
 | 
					        "name" => "my-application1",
 | 
				
			||||||
 | 
					        "title" => null,
 | 
				
			||||||
 | 
					      ], myapp::get()->getParams());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      myapp::init(MyApplication2::class);
 | 
				
			||||||
 | 
					      self::assertSame([
 | 
				
			||||||
 | 
					        "projdir" => $projdir,
 | 
				
			||||||
 | 
					        "vendor" => [
 | 
				
			||||||
 | 
					          "bindir" => "$projdir/vendor/bin",
 | 
				
			||||||
 | 
					          "autoload" => "$projdir/vendor/autoload.php",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "appcode" => "nur-sery",
 | 
				
			||||||
 | 
					        "cwd" => $cwd,
 | 
				
			||||||
 | 
					        "datadir" => "$projdir/devel",
 | 
				
			||||||
 | 
					        "etcdir" => "$projdir/devel/etc",
 | 
				
			||||||
 | 
					        "vardir" => "$projdir/devel/var",
 | 
				
			||||||
 | 
					        "logdir" => "$projdir/devel/log",
 | 
				
			||||||
 | 
					        "profile" => "devel",
 | 
				
			||||||
 | 
					        "appgroup" => null,
 | 
				
			||||||
 | 
					        "name" => "my-application2",
 | 
				
			||||||
 | 
					        "title" => null,
 | 
				
			||||||
 | 
					      ], myapp::get()->getParams());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace nulib\impl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  use nulib\app\cli\Application;
 | 
				
			||||||
 | 
					  use nulib\os\path;
 | 
				
			||||||
 | 
					  use nulib\app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  class config {
 | 
				
			||||||
 | 
					    const PROJDIR = __DIR__.'/..';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static function get_projdir(): string {
 | 
				
			||||||
 | 
					      return path::abspath(self::PROJDIR);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  class myapp extends app {
 | 
				
			||||||
 | 
					    static function reset(): void {
 | 
				
			||||||
 | 
					      self::$app = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  class MyApplication1 extends Application {
 | 
				
			||||||
 | 
					    const PROJDIR = config::PROJDIR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function main() {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  class MyApplication2 extends Application {
 | 
				
			||||||
 | 
					    const PROJDIR = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function main() {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										215
									
								
								tests/php/access/KeyAccessTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								tests/php/access/KeyAccessTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,215 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\php\access;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\tests\TestCase;
 | 
				
			||||||
 | 
					use stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class KeyAccessTest extends TestCase {
 | 
				
			||||||
 | 
					  function testValueAccess() {
 | 
				
			||||||
 | 
					    $default = new stdClass();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $i = null;
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i);
 | 
				
			||||||
 | 
					    self::assertFalse($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $i = false;
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame(false, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $i = "";
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame("", $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $i = null;
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i, null, ["allow_null" => false]);
 | 
				
			||||||
 | 
					    self::assertFalse($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $i = null;
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i, null, ["allow_null" => true]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame(null, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $i = false;
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i, null, ["allow_false" => false]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $i = false;
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i, null, ["allow_false" => true]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame(false, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $i = "";
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i, null, ["allow_empty" => false]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $i = "";
 | 
				
			||||||
 | 
					    $a = new KeyAccess($i, null, ["allow_empty" => true]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame("", $a->get($default));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  function testArrayAccess() {
 | 
				
			||||||
 | 
					    $default = new stdClass();
 | 
				
			||||||
 | 
					    $array = ["null" => null, "false" => false, "empty" => ""];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "inexistant");
 | 
				
			||||||
 | 
					    self::assertFalse($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "null");
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame(null, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "false");
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "empty");
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame("", $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "null", ["allow_null" => false]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "null", ["allow_null" => true]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame(null, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "false", ["allow_false" => false]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "false", ["allow_false" => true]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame(false, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "empty", ["allow_empty" => false]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertFalse($a->available());
 | 
				
			||||||
 | 
					    self::assertSame($default, $a->get($default));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $a = new KeyAccess($array, "empty", ["allow_empty" => true]);
 | 
				
			||||||
 | 
					    self::assertTrue($a->exists());
 | 
				
			||||||
 | 
					    self::assertTrue($a->available());
 | 
				
			||||||
 | 
					    self::assertSame("", $a->get($default));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function _ensureAssoc(?array $orig, ?array $expected, array $keys, ?array $params=null) {
 | 
				
			||||||
 | 
					    $v = $orig; $a = new KeyAccess($v);
 | 
				
			||||||
 | 
					    $a->ensureAssoc($keys, $params);
 | 
				
			||||||
 | 
					    self::assertSame($expected, $v);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  function testEnsureAssoc() {
 | 
				
			||||||
 | 
					    $keys = ["a", "b", "c"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->_ensureAssoc(null, null, $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc([], [], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc([1], ["a" => 1], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc([1, 2, 3], ["a" => 1, "b" => 2, "c" => 3], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc([1, 2, 3, 4], [3 => 4, "a" => 1, "b" => 2, "c" => 3], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc(["c" => 3, 1], ["c" => 3, "a" => 1], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc(["c" => 3, "b" => 2, 1], ["c" => 3, "b" => 2, "a" => 1], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc(["c" => 3, "b" => 2, "a" => 1], ["c" => 3, "b" => 2, "a" => 1], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc(["a" => 1, 2], ["a" => 1, "b" => 2], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc([2, "a" => 1], ["a" => 1, "b" => 2], $keys);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $keys = [0, "a", "b"];
 | 
				
			||||||
 | 
					    $this->_ensureAssoc([1], [1], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureAssoc([1, 2], [1, "a" => 2], $keys);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function _ensureKeys(?array $orig, ?array $expected, array $defaults, ?array $params=null) {
 | 
				
			||||||
 | 
					    $v = $orig; $a = new KeyAccess($v);
 | 
				
			||||||
 | 
					    $a->ensureKeys($defaults, $missings, $params);
 | 
				
			||||||
 | 
					    self::assertSame($expected, $v);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  function testEnsureKeys() {
 | 
				
			||||||
 | 
					    $defaults = ["a" => false, "b" => false, "c" => false];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->_ensureKeys(null, ["a" => false, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureKeys([], ["a" => false, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureKeys(["a" => 1], ["a" => 1, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureKeys(["a" => 1, "b" => 2, "c" => 3], ["a" => 1, "b" => 2, "c" => 3], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureKeys(["x"], ["x", "a" => false, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureKeys(["x", "a" => 1], ["x", "a" => 1, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureKeys(["a" => 1, "x"], ["a" => 1, "x", "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureKeys(["a" => 1, "b" => 2, "c" => 3, "x"], ["a" => 1, "b" => 2, "c" => 3, "x"], $defaults);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function _ensureOrder(?array $orig, ?array $expected, array $keys, ?array $params=null) {
 | 
				
			||||||
 | 
					    $v = $orig; $a = new KeyAccess($v);
 | 
				
			||||||
 | 
					    $a->ensureOrder($keys, $params);
 | 
				
			||||||
 | 
					    self::assertSame($expected, $v);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  function testEnsureOrder() {
 | 
				
			||||||
 | 
					    $keys = ["a", "b", "c"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->_ensureOrder(null, null, $keys);
 | 
				
			||||||
 | 
					    $this->_ensureOrder([], [], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureOrder([1], [1], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureOrder(["b" => 2, "a" => 1], ["a" => 1, "b" => 2], $keys);
 | 
				
			||||||
 | 
					    $this->_ensureOrder(["c" => 3, "a" => 1], ["a" => 1, "c" => 3], $keys);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private function _ensureAssocKeysOrder(?array $orig, ?array $expected, array $defaults, ?array $params=null) {
 | 
				
			||||||
 | 
					    $v = $orig; $a = new KeyAccess($v);
 | 
				
			||||||
 | 
					    $keys = array_keys($defaults);
 | 
				
			||||||
 | 
					    $a->ensureAssoc($keys, $params);
 | 
				
			||||||
 | 
					    $a->ensureKeys($defaults, $missings, $params);
 | 
				
			||||||
 | 
					    $a->ensureOrder($keys, $params);
 | 
				
			||||||
 | 
					    self::assertSame($expected, $v);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  function testEnsureAssocKeysOrder() {
 | 
				
			||||||
 | 
					    $defaults = ["a" => false, "b" => false, "c" => false];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder(null, ["a" => false, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder([], ["a" => false, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder([1], ["a" => 1, "b" => false, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder([1, 2, 3], ["a" => 1, "b" => 2, "c" => 3], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder([1, 2, 3, 4], ["a" => 1, "b" => 2, "c" => 3, 4], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder([1, 2, 3, 4], ["a" => 1, "b" => 2, "c" => 3, 3 => 4], $defaults, [
 | 
				
			||||||
 | 
					      "preserve_keys" => true,
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder(["c" => 3, 1], ["a" => 1, "b" => false, "c" => 3], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, 1], ["a" => 1, "b" => 2, "c" => 3], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder(["c" => 3, "b" => 2, "a" => 1], ["a" => 1, "b" => 2, "c" => 3], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder(["a" => 1, 2], ["a" => 1, "b" => 2, "c" => false], $defaults);
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder([2, "a" => 1], ["a" => 1, "b" => 2, "c" => false], $defaults);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->_ensureAssocKeysOrder([1], ["x_a" => 1, "x_b" => false, "x_c" => false], $defaults, [
 | 
				
			||||||
 | 
					      "key_prefix" => "x_",
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\coll;
 | 
					namespace nulib\php\coll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Exception;
 | 
					use Exception;
 | 
				
			||||||
use nulib\cl;
 | 
					use nulib\cl;
 | 
				
			||||||
@ -1,9 +1,9 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\content;
 | 
					namespace nulib\php\content;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\php\content\c;
 | 
					use nulib\php\content\c;
 | 
				
			||||||
use nur\sery\wip\php\content\impl\html;
 | 
					use nulib\php\content\impl\html;
 | 
				
			||||||
use nur\sery\wip\web\content\v;
 | 
					use nulib\web\content\v;
 | 
				
			||||||
use PHPUnit\Framework\TestCase;
 | 
					use PHPUnit\Framework\TestCase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cTest extends TestCase {
 | 
					class cTest extends TestCase {
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\content\impl;
 | 
					namespace nulib\php\content\impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\php\content\IContent;
 | 
					use nulib\php\content\IContent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\content\impl;
 | 
					namespace nulib\php\content\impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\php\content\IPrintable;
 | 
					use nulib\php\content\IPrintable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\content\impl;
 | 
					namespace nulib\php\content\impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nulib\php\content\c;
 | 
					use nulib\php\content\c;
 | 
				
			||||||
use nulib\php\content\IContent;
 | 
					use nulib\php\content\IContent;
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\php\content\impl;
 | 
					namespace nulib\php\content\impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class html {
 | 
					class html {
 | 
				
			||||||
  const H1 = [self::class, "h1"];
 | 
					  const H1 = [self::class, "h1"];
 | 
				
			||||||
							
								
								
									
										396
									
								
								tests/schema/_assoc/AssocSchemaTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								tests/schema/_assoc/AssocSchemaTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,396 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\schema\_assoc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\ext\yaml;
 | 
				
			||||||
 | 
					use nulib\tests\TestCase;
 | 
				
			||||||
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					use nulib\schema\_scalar\ScalarSchemaTest;
 | 
				
			||||||
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
 | 
					use PHPStan\Type\Enum\EnumCaseObjectType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AssocSchemaTest extends TestCase {
 | 
				
			||||||
 | 
					  const NULL_SCHEMA = [
 | 
				
			||||||
 | 
					    "" => [
 | 
				
			||||||
 | 
					      "assoc",
 | 
				
			||||||
 | 
					      "compute_func" => null,
 | 
				
			||||||
 | 
					      "validate_func" => null,
 | 
				
			||||||
 | 
					      "ensure_array" => null,
 | 
				
			||||||
 | 
					      "ensure_assoc" => null,
 | 
				
			||||||
 | 
					      "ensure_keys" => null,
 | 
				
			||||||
 | 
					      "ensure_order" => null,
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "schema" => null,
 | 
				
			||||||
 | 
					    "type" => [null],
 | 
				
			||||||
 | 
					    "default" => null,
 | 
				
			||||||
 | 
					    "title" => null,
 | 
				
			||||||
 | 
					    "required" => false,
 | 
				
			||||||
 | 
					    "nullable" => true,
 | 
				
			||||||
 | 
					    "desc" => null,
 | 
				
			||||||
 | 
					    "analyzer_func" => null,
 | 
				
			||||||
 | 
					    "extractor_func" => null,
 | 
				
			||||||
 | 
					    "parser_func" => null,
 | 
				
			||||||
 | 
					    "normalizer_func" => null,
 | 
				
			||||||
 | 
					    "messages" => null,
 | 
				
			||||||
 | 
					    "formatter_func" => null,
 | 
				
			||||||
 | 
					    "format" => null,
 | 
				
			||||||
 | 
					    "size" => null,
 | 
				
			||||||
 | 
					    "precision" => null,
 | 
				
			||||||
 | 
					    "name" => null,
 | 
				
			||||||
 | 
					    "pkey" => null,
 | 
				
			||||||
 | 
					    "header" => null,
 | 
				
			||||||
 | 
					    "computed" => null,
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static function schema(array $definition, array $keyDefinitions): array {
 | 
				
			||||||
 | 
					    $definition = array_merge(self::NULL_SCHEMA, $definition, ["schema" => []]);
 | 
				
			||||||
 | 
					    foreach ($keyDefinitions as $key => $keydef) {
 | 
				
			||||||
 | 
					      $definition["schema"][$key] = array_merge(ScalarSchemaTest::NULL_SCHEMA, $keydef);
 | 
				
			||||||
 | 
					    }; unset($subdef);
 | 
				
			||||||
 | 
					    return $definition;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testNormalize() {
 | 
				
			||||||
 | 
					    self::assertSame(self::schema([
 | 
				
			||||||
 | 
					      "type" => ["array"], "nullable" => true,
 | 
				
			||||||
 | 
					    ], [
 | 
				
			||||||
 | 
					      "s" => [
 | 
				
			||||||
 | 
					        "type" => ["string"], "nullable" => false,
 | 
				
			||||||
 | 
					        "name" => "s", "pkey" => "s", "header" => "s",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    ]), AssocSchema::normalize_definition(["s" => "string"]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertSame(self::schema([
 | 
				
			||||||
 | 
					      "type" => ["array"], "nullable" => true,
 | 
				
			||||||
 | 
					    ], [
 | 
				
			||||||
 | 
					      "s" => [
 | 
				
			||||||
 | 
					        "type" => ["string"], "nullable" => false,
 | 
				
			||||||
 | 
					        "name" => "s", "pkey" => "s", "header" => "s",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "i" => [
 | 
				
			||||||
 | 
					        "type" => ["int"], "nullable" => false,
 | 
				
			||||||
 | 
					        "name" => "i", "pkey" => "i", "header" => "i",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "b" => [
 | 
				
			||||||
 | 
					        "type" => ["bool"], "nullable" => false,
 | 
				
			||||||
 | 
					        "name" => "b", "pkey" => "b", "header" => "b",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    ]), AssocSchema::normalize_definition([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => "int",
 | 
				
			||||||
 | 
					      "b" => "bool",
 | 
				
			||||||
 | 
					    ]));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testConstructor() {
 | 
				
			||||||
 | 
					    $schema = new AssocSchema([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => "int",
 | 
				
			||||||
 | 
					      "b" => "bool",
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    self::assertSame(self::schema([
 | 
				
			||||||
 | 
					      "type" => ["array"], "nullable" => true,
 | 
				
			||||||
 | 
					    ], [
 | 
				
			||||||
 | 
					      "s" => [
 | 
				
			||||||
 | 
					        "type" => ["string"], "nullable" => false,
 | 
				
			||||||
 | 
					        "name" => "s", "pkey" => "s", "header" => "s",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "i" => [
 | 
				
			||||||
 | 
					        "type" => ["int"], "nullable" => false,
 | 
				
			||||||
 | 
					        "name" => "i", "pkey" => "i", "header" => "i",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      "b" => [
 | 
				
			||||||
 | 
					        "type" => ["bool"], "nullable" => false,
 | 
				
			||||||
 | 
					        "name" => "b", "pkey" => "b", "header" => "b",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    ]), $schema->getDefinition());
 | 
				
			||||||
 | 
					    //yaml::dump($schema->getDefinition());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testWrapper() {
 | 
				
			||||||
 | 
					    $schema = new AssocSchema([
 | 
				
			||||||
 | 
					      "s" => "?string",
 | 
				
			||||||
 | 
					      "i" => "?int",
 | 
				
			||||||
 | 
					      "b" => "?bool",
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    $array = ["s" => "  string  ", "i" => "  42 ", "b" => false];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => 42,
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ###########################################################################
 | 
				
			||||||
 | 
					    $schema = new AssocSchema([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => "int",
 | 
				
			||||||
 | 
					      "b" => "bool",
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = ["s" => "  string  "];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => 0,
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = ["b" => false, "s" => "  string  "];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => 0,
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = ["s" => "  string  "];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array, null, ["ensure_order" => false]);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => 0,
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = ["b" => false, "s" => "  string  "];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array, null, ["ensure_order" => false]);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "i" => 0,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = ["s" => "  string  "];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array, null, ["ensure_keys" => false]);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = ["b" => false, "s" => "  string  "];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array, null, ["ensure_keys" => false]);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "s" => "string",
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // false équivaut à absent, sauf pour "b" qui est de type bool
 | 
				
			||||||
 | 
					    $array = ["s" => false, "i" => false, "b" => false];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array, null, ["ensure_keys" => true]);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "s" => "",
 | 
				
			||||||
 | 
					      "i" => 0,
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = ["s" => false, "i" => false, "b" => false];
 | 
				
			||||||
 | 
					    $schema->getWrapper($array, null, ["ensure_keys" => false]);
 | 
				
			||||||
 | 
					    self::assertSame([
 | 
				
			||||||
 | 
					      "b" => false,
 | 
				
			||||||
 | 
					    ], $array);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const STRING_SCHEMA = [
 | 
				
			||||||
 | 
					    "s" => "string",
 | 
				
			||||||
 | 
					    "f" => "string",
 | 
				
			||||||
 | 
					    "m" => "string",
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const NSTRING_SCHEMA = [
 | 
				
			||||||
 | 
					    "s" => "?string",
 | 
				
			||||||
 | 
					    "f" => "?string",
 | 
				
			||||||
 | 
					    "m" => "?string",
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const RSTRING_SCHEMA = [
 | 
				
			||||||
 | 
					    "s" => ["string", "required" => true],
 | 
				
			||||||
 | 
					    "f" => ["string", "required" => true],
 | 
				
			||||||
 | 
					    "m" => ["string", "required" => true],
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const RNSTRING_SCHEMA = [
 | 
				
			||||||
 | 
					    "s" => ["?string", "required" => true],
 | 
				
			||||||
 | 
					    "f" => ["?string", "required" => true],
 | 
				
			||||||
 | 
					    "m" => ["?string", "required" => true],
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const STRINGS = ["s" => "string", "f" => false];
 | 
				
			||||||
 | 
					  const NSTRINGS = ["s" => null, "f" => null];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testString() {
 | 
				
			||||||
 | 
					    /** @var AssocSchema $schema */
 | 
				
			||||||
 | 
					    $schema = Schema::ns(self::STRING_SCHEMA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::STRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => "string", "f" => "", "m" => ""], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertTrue($result->present);
 | 
				
			||||||
 | 
					    self::assertFalse($result->available);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertNotException(function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::STRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => null, "f" => null, "m" => ""], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertFalse($result->valid);
 | 
				
			||||||
 | 
					    self::assertSame("null", $result->messageKey);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertFalse($result->valid);
 | 
				
			||||||
 | 
					    self::assertSame("null", $result->messageKey);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertException(ValueException::class, function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testNstring() {
 | 
				
			||||||
 | 
					    /** @var AssocSchema $schema */
 | 
				
			||||||
 | 
					    $schema = Schema::ns(self::NSTRING_SCHEMA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::STRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => "string", "f" => null, "m" => null], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertTrue($result->present);
 | 
				
			||||||
 | 
					    self::assertFalse($result->available);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertNotException(function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::STRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => null, "f" => null, "m" => null], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertNotException(function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testRstring() {
 | 
				
			||||||
 | 
					    /** @var AssocSchema $schema */
 | 
				
			||||||
 | 
					    $schema = Schema::ns(self::RSTRING_SCHEMA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::STRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => "string", "f" => "", "m" => ""], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertTrue($result->present);
 | 
				
			||||||
 | 
					    self::assertFalse($result->available);
 | 
				
			||||||
 | 
					    self::assertSame("unavailable", $result->messageKey);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					    self::assertSame("missing", $result->messageKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertException(ValueException::class, function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::STRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => null, "f" => null, "m" => ""], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertFalse($result->valid);
 | 
				
			||||||
 | 
					    self::assertSame("null", $result->messageKey);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertFalse($result->valid);
 | 
				
			||||||
 | 
					    self::assertSame("null", $result->messageKey);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					    self::assertSame("missing", $result->messageKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertException(ValueException::class, function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testRnstring() {
 | 
				
			||||||
 | 
					    /** @var AssocSchema $schema */
 | 
				
			||||||
 | 
					    $schema = Schema::ns(self::RNSTRING_SCHEMA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::STRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => "string", "f" => null, "m" => null], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertTrue($result->present);
 | 
				
			||||||
 | 
					    self::assertFalse($result->available);
 | 
				
			||||||
 | 
					    self::assertSame("unavailable", $result->messageKey);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					    self::assertSame("missing", $result->messageKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertException(ValueException::class, function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::STRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper($array, null, ["throw" => false]);
 | 
				
			||||||
 | 
					    self::assertSame(["s" => null, "f" => null, "m" => null], $array);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("s");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("f");
 | 
				
			||||||
 | 
					    self::assertTrue($result->normalized);
 | 
				
			||||||
 | 
					    $result = $wrapper->getResult("m");
 | 
				
			||||||
 | 
					    self::assertFalse($result->present);
 | 
				
			||||||
 | 
					    self::assertSame("missing", $result->messageKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self::assertException(ValueException::class, function() use ($schema) {
 | 
				
			||||||
 | 
					      $array = self::NSTRINGS;
 | 
				
			||||||
 | 
					      $schema->getWrapper($array);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testMessage() {
 | 
				
			||||||
 | 
					    $schema = new AssocSchema([
 | 
				
			||||||
 | 
					      "rs" => ["string", "required" => true],
 | 
				
			||||||
 | 
					      "i" => ["int"],
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $value = [];
 | 
				
			||||||
 | 
					    $result = $schema->getWrapper($value, null, ["throw" => false])->getResult(null);
 | 
				
			||||||
 | 
					    $expectedMessage = <<<EOT
 | 
				
			||||||
 | 
					rs: vous devez spécifier cette valeur
 | 
				
			||||||
 | 
					EOT;
 | 
				
			||||||
 | 
					    self::assertSame($expectedMessage, $result->message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $value = [
 | 
				
			||||||
 | 
					      "rs" => null,
 | 
				
			||||||
 | 
					      "i" => "abc",
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    $result = $schema->getWrapper($value, null, ["throw" => false])->getResult(null);
 | 
				
			||||||
 | 
					    $expectedMessage = <<<EOT
 | 
				
			||||||
 | 
					rs: cette valeur ne doit pas être nulle
 | 
				
			||||||
 | 
					i: une valeur numérique entière est attendue
 | 
				
			||||||
 | 
					EOT;
 | 
				
			||||||
 | 
					    self::assertSame($expectedMessage, $result->message);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										70
									
								
								tests/schema/_scalar/ScalarSchemaTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								tests/schema/_scalar/ScalarSchemaTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\schema\_scalar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\tests\TestCase;
 | 
				
			||||||
 | 
					use nulib\schema\SchemaException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ScalarSchemaTest extends TestCase {
 | 
				
			||||||
 | 
					  const NULL_SCHEMA = [
 | 
				
			||||||
 | 
					    "type" => [null],
 | 
				
			||||||
 | 
					    "default" => null,
 | 
				
			||||||
 | 
					    "title" => null,
 | 
				
			||||||
 | 
					    "required" => false,
 | 
				
			||||||
 | 
					    "nullable" => true,
 | 
				
			||||||
 | 
					    "desc" => null,
 | 
				
			||||||
 | 
					    "analyzer_func" => null,
 | 
				
			||||||
 | 
					    "extractor_func" => null,
 | 
				
			||||||
 | 
					    "parser_func" => null,
 | 
				
			||||||
 | 
					    "normalizer_func" => null,
 | 
				
			||||||
 | 
					    "messages" => null,
 | 
				
			||||||
 | 
					    "formatter_func" => null,
 | 
				
			||||||
 | 
					    "format" => null,
 | 
				
			||||||
 | 
					    "size" => null,
 | 
				
			||||||
 | 
					    "precision" => null,
 | 
				
			||||||
 | 
					    "" => [
 | 
				
			||||||
 | 
					      "scalar",
 | 
				
			||||||
 | 
					      "compute_func" => null,
 | 
				
			||||||
 | 
					      "validate_func" => null,
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "schema" => null,
 | 
				
			||||||
 | 
					    "name" => null,
 | 
				
			||||||
 | 
					    "pkey" => null,
 | 
				
			||||||
 | 
					    "header" => null,
 | 
				
			||||||
 | 
					    "computed" => null,
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static function schema(array $schema): array {
 | 
				
			||||||
 | 
					    return array_merge(self::NULL_SCHEMA, $schema);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testNormalize() {
 | 
				
			||||||
 | 
					    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize_definition(null));
 | 
				
			||||||
 | 
					    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize_definition([]));
 | 
				
			||||||
 | 
					    self::assertSame(self::NULL_SCHEMA, ScalarSchema::normalize_definition([null]));
 | 
				
			||||||
 | 
					    self::assertException(SchemaException::class, function () {
 | 
				
			||||||
 | 
					      ScalarSchema::normalize_definition([[]]);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    self::assertException(SchemaException::class, function () {
 | 
				
			||||||
 | 
					      ScalarSchema::normalize_definition([[null]]);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $string = self::schema(["type" => ["string"], "nullable" => false]);
 | 
				
			||||||
 | 
					    self::assertSame($string, ScalarSchema::normalize_definition("string"));
 | 
				
			||||||
 | 
					    self::assertSame($string, ScalarSchema::normalize_definition(["string"]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $nstring = self::schema(["type" => ["string"]]);
 | 
				
			||||||
 | 
					    self::assertSame($nstring, ScalarSchema::normalize_definition(["?string"]));
 | 
				
			||||||
 | 
					    self::assertSame($nstring, ScalarSchema::normalize_definition(["?string|null"]));
 | 
				
			||||||
 | 
					    self::assertSame($nstring, ScalarSchema::normalize_definition(["string|null"]));
 | 
				
			||||||
 | 
					    self::assertSame($nstring, ScalarSchema::normalize_definition([["?string", "null"]]));
 | 
				
			||||||
 | 
					    self::assertSame($nstring, ScalarSchema::normalize_definition([["string", "null"]]));
 | 
				
			||||||
 | 
					    self::assertSame($nstring, ScalarSchema::normalize_definition([["string", null]]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $key = self::schema(["type" => ["string", "int"], "nullable" => false]);
 | 
				
			||||||
 | 
					    self::assertSame($key, ScalarSchema::normalize_definition("string|int"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $nkey = self::schema(["type" => ["string", "int"], "nullable" => true]);
 | 
				
			||||||
 | 
					    self::assertSame($nkey, ScalarSchema::normalize_definition("?string|int"));
 | 
				
			||||||
 | 
					    self::assertSame($nkey, ScalarSchema::normalize_definition("string|?int"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										296
									
								
								tests/schema/_scalar/ScalarWrapperTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								tests/schema/_scalar/ScalarWrapperTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,296 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nulib\schema\_scalar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nulib\tests\TestCase;
 | 
				
			||||||
 | 
					use nulib\ValueException;
 | 
				
			||||||
 | 
					use nulib\schema\input\Input;
 | 
				
			||||||
 | 
					use stdClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ScalarWrapperTest extends TestCase {
 | 
				
			||||||
 | 
					  function checkValue(ScalarWrapper $wrapper, $value, bool $present, bool $available, bool $valid, bool $normalized): void {
 | 
				
			||||||
 | 
					    self::assertSame($value, $wrapper->get(), "value");
 | 
				
			||||||
 | 
					    self::assertSame($present, $wrapper->isPresent(), "present");
 | 
				
			||||||
 | 
					    self::assertSame($available, $wrapper->isAvailable(), "available");
 | 
				
			||||||
 | 
					    self::assertSame($valid, $wrapper->isValid(), "valid");
 | 
				
			||||||
 | 
					    self::assertSame($normalized, $wrapper->isNormalized(), "normalized");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function checkNormalize(ScalarSchema $schema, $orig, bool $normalize, $value, bool $present, bool $available, bool $valid, bool $normalized, ?array $inputParams=null): void {
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper();
 | 
				
			||||||
 | 
					    $wrapper->resetParams(["normalize" => $normalize]);
 | 
				
			||||||
 | 
					    if ($inputParams !== null) $input = new Input($orig, $inputParams);
 | 
				
			||||||
 | 
					    else $input = $orig;
 | 
				
			||||||
 | 
					    $wrapper->reset($input);
 | 
				
			||||||
 | 
					    $this->checkValue($wrapper, $value, $present, $available, $valid, $normalized);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function checkException(ScalarSchema $schema, $orig, bool $normalize, string $exceptionClass, ?array $inputParams=null) {
 | 
				
			||||||
 | 
					    $wrapper = $schema->getWrapper();
 | 
				
			||||||
 | 
					    if ($inputParams !== null) $orig = new Input($orig, $inputParams);
 | 
				
			||||||
 | 
					    self::assertException($exceptionClass, function() use ($wrapper, &$orig, $normalize) {
 | 
				
			||||||
 | 
					      $wrapper->resetParams(["normalize" => $normalize]);
 | 
				
			||||||
 | 
					      $wrapper->reset($orig);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testRaw() {
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, false, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, false, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $obj = new stdClass();
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("raw");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, false, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, false, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $obj = new stdClass();
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testMixed() {
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("mixed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, false, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, false, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $obj = new stdClass();
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("?mixed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, false, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, false, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $obj = new stdClass();
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, false, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, $obj, true, $obj, true, true, true, true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testRawstring() {
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("rawstring");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, null, true, false, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, null, true, false, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, "", true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, "", true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "   ", false, "   ", true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "   ", true, "   ", true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "text", false, "text", true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "text", true, "text", true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "  text  ", false, "  text  ", true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "  text  ", true, "  text  ", true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, true, false, true, true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, true, true, "1", true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, 42, false, 42, true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, 42, true, "42", true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, [], false, [], true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, [], true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester valeur par défaut
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema(["rawstring", null]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, null, true, false, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, null, true, false, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema(["rawstring", "default"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, "default", true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, "default", true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester nullable
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("?rawstring");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester required
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema(["rawstring", "required" => true]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, null, true, false, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, false, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester allow_empty === false
 | 
				
			||||||
 | 
					    $inputParams = ["allow_empty" => false];
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("rawstring");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("?rawstring");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testString() {
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, null, true, false, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, null, true, false, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, "", true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, "", true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "   ", false, "", true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "   ", true, "", true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "text", false, "text", true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "text", true, "text", true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "  text  ", false, "text", true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "  text  ", true, "text", true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, true, false, true, true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, true, true, "1", true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, 42, false, 42, true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, 42, true, "42", true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, [], false, [], true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, [], true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester nullable
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("?string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester required
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema(["string", "required" => true]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, null, true, false, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, false, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester allow_empty === false
 | 
				
			||||||
 | 
					    $inputParams = ["allow_empty" => false];
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("?string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function testInt() {
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("int");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, null, true, false, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, true, null, true, false, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, 42, false, 42, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, 42, true, 42, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "42", false, "42", true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "42", true, 42, true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "42.5", false, "42.5", true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "42.5", true, 42, true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "42,5", false, "42,5", true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "42,5", true, 42, true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "  42  ", false, "42", true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "  42  ", true, 42, true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, "", true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, "", true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "   ", false, "   ", true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, "   ", true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "text", false, "text", true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, "text", true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, true, false, true, true, true, true, false);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, true, true, 1, true, true, true, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, [], false, [], true, true, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, [], true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester nullable
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("?int");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester required
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema(["int", "required" => true]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, false, false, null, true, false, false, false);
 | 
				
			||||||
 | 
					    $this->checkException($schema, false, true, ValueException::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ## Tester allow_empty === false
 | 
				
			||||||
 | 
					    $inputParams = ["allow_empty" => false];
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("int");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, false, false, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkException($schema, null, true, ValueException::class, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $schema = new ScalarSchema("?int");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, false, null, true, true, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, null, true, null, true, true, true, true, $inputParams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", false, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					    $this->checkNormalize($schema, "", true, null, true, false, true, true, $inputParams);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\wip\schema\types;
 | 
					namespace nulib\schema\types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Exception;
 | 
					use Exception;
 | 
				
			||||||
use nulib\tests\TestCase;
 | 
					use nulib\tests\TestCase;
 | 
				
			||||||
use nur\sery\wip\schema\_scalar\ScalarWrapper;
 | 
					use nulib\schema\_scalar\ScalarWrapper;
 | 
				
			||||||
use nur\sery\wip\schema\Schema;
 | 
					use nulib\schema\Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class boolTest extends TestCase {
 | 
					class boolTest extends TestCase {
 | 
				
			||||||
  function commonTests($wrapper, &$value, callable $wrapperSetter): void {
 | 
					  function commonTests($wrapper, &$value, callable $wrapperSetter): void {
 | 
				
			||||||
@ -59,7 +59,7 @@ class boolTest extends TestCase {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  function testBool() {
 | 
					  function testBool() {
 | 
				
			||||||
    /** @var ScalarWrapper $wrapper */
 | 
					    /** @var ScalarWrapper $wrapper */
 | 
				
			||||||
    Schema::nw($value, null, $schema, "bool", $wrapper);
 | 
					    Schema::nw($value, null, "bool", $schema, $wrapper);
 | 
				
			||||||
    $wrapperSetter = function($value) use($wrapper) {
 | 
					    $wrapperSetter = function($value) use($wrapper) {
 | 
				
			||||||
      return function() use($wrapper, $value) {
 | 
					      return function() use($wrapper, $value) {
 | 
				
			||||||
        $wrapper->set($value);
 | 
					        $wrapper->set($value);
 | 
				
			||||||
@ -75,7 +75,7 @@ class boolTest extends TestCase {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  function testNbool() {
 | 
					  function testNbool() {
 | 
				
			||||||
    /** @var ScalarWrapper $wrapper */
 | 
					    /** @var ScalarWrapper $wrapper */
 | 
				
			||||||
    Schema::nw($value, null, $schema, "?bool", $wrapper);
 | 
					    Schema::nw($value, null, "?bool", $schema, $wrapper);
 | 
				
			||||||
    $wrapperSetter = function($value) use($wrapper) {
 | 
					    $wrapperSetter = function($value) use($wrapper) {
 | 
				
			||||||
      return function() use($wrapper, $value) {
 | 
					      return function() use($wrapper, $value) {
 | 
				
			||||||
        $wrapper->set($value);
 | 
					        $wrapper->set($value);
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user