@bohwaz, aurais-tu une idée de l’erreur ? Je ne vois pas comment l’entité utilisateur peut être instanciée correctement avec les champs dynamiques par ce biais.
RuntimeException: Missing key in array: anciennete in /var/www/paheko/production/src/include/lib/KD2/DB/AbstractEntity.php:134
Stack trace:
#0 /var/www/paheko/production/src/include/lib/KD2/DB/EntityManager.php(195): KD2\DB\AbstractEntity->load(Array)
#1 /var/www/paheko/production/src/include/lib/KD2/DB/EntityManager.php(94): KD2\DB\EntityManager->one('...', 9)
#2 /var/www/paheko/production/src/include/lib/Paheko/Users/Users.php(454): KD2\DB\EntityManager::findOne('...', '...', 9)
#3 /var/www/paheko/production/src/www/admin/config/users/index.php(31): Paheko\Users\Users::getFirstAdmin()
#4 {main}
<errorReport>
{
"errors": [
{
"message": "Missing key in array: anciennete",
"errorCode": 0,
"type": "RuntimeException",
"backtrace": [
{
"file": "...\/include\/lib\/KD2\/DB\/AbstractEntity.php",
"line": 134,
"code": {
"130": "\t\t}",
"131": "",
"132": "\t\tforeach ($properties as $name => $prop) {",
"133": "\t\t\tif (!array_key_exists($name, $data)) {",
"134": "\t\t\t\tthrow new \\RuntimeException('Missing key in array: ' . $name);",
"135": "\t\t\t}",
"136": "",
"137": "\t\t\t$value = $data[$name];",
"138": ""
}
},
{
"function": "KD2\\DB\\AbstractEntity->load",
"file": "...\/include\/lib\/KD2\/DB\/EntityManager.php",
"line": 195,
"args": {
"$data": "array(26) {\n [\"id\"]=> int(1)\n [\"id_category\"]=> int(3)\n [\"date_login\"]=> NULL\n [\"date_updated\"]=> string(19) \"2026-02-02 16:58:40\"\n [\"otp_secret\"]=> NULL\n [\"otp_recovery_codes\"]=> NULL\n [\"pgp_key\"]=> NULL\n [\"id_parent\"]=> NULL\n [\"is_parent\"]=> int(0)\n [\"preferences\"]=> NULL\n [\"numero\"]=> int(1)\n [\"nom\"]=> string(5) \"XXX\"\n [\"email\"]=> string(43) \"paheko-noreply+framaspace-xxx@frama.space\"\n [\"password\"]=> string(60) \"xxx\"\n [\"adresse\"]=> NULL\n [\"code_postal\"]=> NULL\n [\"ville\"]=> NULL\n [\"telephone\"]=> NULL\n [\"lettre_infos\"]=> int(0)\n [\"date_inscription\"]=> NULL\n [\"pro_part\"]=> NULL\n [\"siren\"]=> NULL\n [\"forme_juridique\"]=> NULL\n [\"compte_esol\"]=> NULL\n [\"libelle_etablissement_sirene\"]=> NULL\n [\"naf_ape\"]=> NULL\n }"
},
"code": {
"191": "\t\t}",
"192": "",
"193": "\t\t$obj = new $this->class;",
"194": "\t\t$obj->exists(true);",
"195": "\t\t$obj->load($row);",
"196": "\t\treturn $obj;",
"197": "\t}",
"198": "",
"199": "\tpublic function col(string $query, ...$params)"
}
},
{
"function": "KD2\\DB\\EntityManager->one",
"file": "...\/include\/lib\/KD2\/DB\/EntityManager.php",
"line": 94,
"args": {
"$query": "string(106) \"SELECT * FROM users WHERE id_category IN (SELECT id FROM users_categories WHERE perm_config >= ?) LIMIT 1;\"",
"$params": "int(9)"
},
"code": {
"90": "\t * @return null|AbstractEntity",
"91": "\t *\/",
"92": "\tstatic public function findOne(string $class, string $query, ...$params)",
"93": "\t{",
"94": "\t\treturn self::getInstance($class)->one($query, ...$params);",
"95": "\t}",
"96": "",
"97": "\t\/**",
"98": "\t * Returns an Entity from its ID"
}
},
{
"function": "KD2\\DB\\EntityManager::findOne",
"file": "...\/include\/lib\/Paheko\/Users\/Users.php",
"line": 454,
"args": {
"$class": "string(26) \"Paheko\\Entities\\Users\\User\"",
"$query": "string(107) \"SELECT * FROM @TABLE WHERE id_category IN (SELECT id FROM users_categories WHERE perm_config >= ?) LIMIT 1;\"",
"$params": "int(9)"
},
"code": {
"450": "\t}",
"451": "",
"452": "\tstatic public function getFirstAdmin(): ?User",
"453": "\t{",
"454": "\t\treturn EM::findOne(User::class, 'SELECT * FROM @TABLE WHERE id_category IN (SELECT id FROM users_categories WHERE perm_config >= ?) LIMIT 1;',",
"455": "\t\t\tSession::ACCESS_ADMIN);",
"456": "\t}",
"457": "",
"458": "\tstatic public function getNewNumber(): ?int"
}
},
{
"function": "Paheko\\Users\\Users::getFirstAdmin",
"file": "...\/www\/admin\/config\/users\/index.php",
"line": 31,
"code": {
"27": "",
"28": "$names = $df->listAssocNames();",
"29": "$name_fields = array_intersect_key($names, array_flip(DynamicFields::getNameFields()));",
"30": "",
"31": "$first_admin_user = LOCAL_LOGIN !== null ? Users::getFirstAdmin() : null;",
"32": "",
"33": "$tpl->assign([",
"34": "\t'has_parents' => Users::hasParents(),",
"35": "\t'users_categories' => Categories::listAssoc(),"
}
}
]
}
],
"context": {
"date": "2026-03-04T15:48:42+01:00",
"duration": 9.3841552734375,
"environment": "production:5",
"hostname": "~.*\\.paheko\\.frama.space",
"http_files": "array(0) {\n }",
"http_method": "GET",
"http_post": "array(0) {\n }",
"http_referrer": "https:\/\/xxx.paheko.frama.space\/admin\/config\/",
"http_user_agent": "Mozilla\/5.0 (X11; Linux x86_64; rv:150.0) Gecko\/20100101 Firefox\/150.0",
"id": "6rrjxmae",
"language": "PHP 8.2.30",
"memory_peak": 8388608,
"memory_used": 8388608,
"os": "Linux",
"paheko_data_root": "\/var\/www\/paheko-data\/instances\/xxx",
"paheko_version": "1.3.15",
"php_sapi": "fpm-fcgi",
"remote_ip": "xxx",
"root_directory": "\/var\/www\/paheko\/production\/src",
"server_addr": "xxx",
"sqlite_journal": "WAL",
"user_addr": "xxx",
"url": "https:\/\/xxx.paheko.frama.space\/admin\/config\/users\/"
}
}
</errorReport>
L’entrée dans config_users_fields :
18|anciennete|17|virtual|Ancienneté||0|1|1|0|[]|||32
La table contient également d’autres champs supplémentaires non virtuels, qu’on retrouve également dans users.
La vue users_view contient bien anciennete.