Toujours accepter des vrais booléens pour les saisies déclarées en php #147

Open
opened 1 month ago by tcharlss · 11 comments
tcharlss commented 1 month ago
Owner

Certaines options des saisies sont conceptuellement des booléens, mais on peut utiliser le texte oui ou non comme valeur, ça ok pas de problème : c'est pour contourner les limites posées par certains cas d'usages.

Par contre quand on déclare les saisies "proprement" en php, on devrait toutjours pouvoir passer une vraie valeur booléenne et pas le pseudo oui|non.

Actuellement c'est un peu du 50/50, pour certaines options ça passe, pour d'autres pas, on se retrouve avec un mélange pas joli joli :

'options' => [
    'multiple' => true,
    'readonly' => 'oui', // le booléen marche pas
]

Donc faudra faire une passe pour harmoniser tout ça amha.

Certaines options des saisies sont conceptuellement des booléens, mais on peut utiliser le texte `oui` ou `non` comme valeur, ça ok pas de problème : c'est pour contourner les limites posées par certains cas d'usages. Par contre quand on déclare les saisies "proprement" en php, on devrait toutjours pouvoir passer une vraie valeur booléenne et pas le pseudo oui|non. Actuellement c'est un peu du 50/50, pour certaines options ça passe, pour d'autres pas, on se retrouve avec un mélange pas joli joli : ```php 'options' => [ 'multiple' => true, 'readonly' => 'oui', // le booléen marche pas ] ``` Donc faudra faire une passe pour harmoniser tout ça amha.
Collaborator

Tu aurais un exemple de où cela passe ? pour voir comment on gère concrètement cela dans les squelettes ?

Tu aurais un exemple de où cela passe ? pour voir comment on gère concrètement cela dans les squelettes ?

Ça risque de pas être évident.

Ça risque de pas être évident.
Collaborator

Faudrait voir un exemple qui marche.

Mais plus globalement je me dit que c'est un problème plus globale à SPIP non, le"comment passer un booléen à un squelette" ?

Faudrait voir un exemple qui marche. Mais plus globalement je me dit que c'est un problème plus globale à SPIP non, le"comment passer un booléen à un squelette" ?
Poster
Owner

Alors ça se passe en 2 endroits :

  • Les valeurs des options communes à toutes les saisies sont normalisées dans _base.html, il y en a 3 : obligatoire, readonly et disable
  • Ensuite il y a celles propres à chaque saisie : multiple, etc.

Par ordre de priorité, je pense qu'il faudrait régler :

  1. Au moins les 3 options communes à toutes les saisies.
  2. Ensuite les options des saisies de base : input, select, radio, checkbox. En gros celles qu'on classe dans « Champ libre » et « choix restreints ».
  3. Et ensuite, les autres

Pour les exemples qui marchent pas, on a readonly=true et obligatoire=true.

Et à l'inverse multiple=true fonctionne dans la saisie selection par exemple, mais multiple="non" ne fonctionne pas !

Si c'est pas forcément évident à régler, c'est pas non plus impossible :)
Pour normaliser dans toutes les saisies, il faudrait peut-être passer par un filtre |saisies_booleen afin d'avoir le même résultat partout.

Dans les squelettes pour passer un vrai booléen on peut faire #EVAL{true}, mais là c'est plus une question propre à saisies, car on décide d'accepter en plus les pseudos valeurs oui-non pour simplifier.

Tests

J'ai commencé à tester quelques options avec ça (readonly, multiple et obligatoire) :

function formulaires_test_booleens_saisies_dist() {

	// Les valeurs à tester
	$valeurs = [true, 'oui', false, 'non'];

	// Les options à tester, et avec quelles saisies
	$tests = [
		'readonly' => [
			'saisie' => 'input',
			'valeurs_erreurs' => [true],
		],
		'multiple' => [
			'saisie' => 'selection',
			'valeurs_erreurs' => ['non'],
			'options' => [
				'data' => [
					'bonjour' => 'Bonjour',
					'aurevoir' => 'Aurevoir',
				],
				'cacher_option_intro' => 'oui',
			],
		],
		'obligatoire' => [
			'saisie' => 'input',
			'valeurs_erreurs' => [true],
		]
	];

	$saisies = [];
	foreach ($tests as $option => $stuff) {
		$saisies_fieldset = [];
		foreach ($valeurs as $valeur) {
			$ok = in_array($valeur, $stuff['valeurs_erreurs'], true) ? '❌' : '✅';
			$nom_valeur = (is_bool($valeur) ? ($valeur ? 'true' : 'false') : "\"$valeur\"");
			$saisies_fieldset[] = [
				'saisie' => $stuff['saisie'],
				'options' => array_merge($stuff['options'] ?? [], [
					'nom' => "${option}_${valeur}",
					'label' => "$ok $nom_valeur",
					$option => $valeur,
				]),
			];
		}
		$saisies[] = [
			'saisie' => 'fieldset',
			'options' => [
				'nom' => "fieldset_$option",
				'label' => $option,
			],
			'saisies' => $saisies_fieldset,
		];
	}

	return $saisies;
}

Nomenklatura

Un mot sur les 3 options communes à toutes les saisies en passant : on a quand même un beau mélange là :)

attribut html nom de l'option
required obligatoire
readonly readonly
disabled disable

Pour une option c'est le vrai nom anglais de l'attribut html (readonly), pour l'autre c'est du français (obligatoire), et pour la dernière c'est de l'anglais mais pas le vrai nom de l'attribut (disable sans 'd' à la fin).

Tant qu'à faire je propose de prendre en priorité le vrai nom des attributs html, et garder les autres en fallback → #ENV{required, #ENV{obligatoire}} etc.

Alors ça se passe en 2 endroits : * Les valeurs des options communes à toutes les saisies sont normalisées dans [\_base.html](https://git.spip.net/spip-contrib-extensions/saisies/src/branch/master/saisies/_base.html#L36-L39), il y en a 3 : `obligatoire`, `readonly` et `disable` * Ensuite il y a celles propres à chaque saisie : `multiple`, etc. Par ordre de priorité, je pense qu'il faudrait régler : 1. Au moins les 3 options communes à toutes les saisies. 2. Ensuite les options des saisies de base : input, select, radio, checkbox. En gros celles qu'on classe dans « Champ libre » et « choix restreints ». 3. Et ensuite, les autres Pour les exemples qui marchent pas, on a `readonly=true` et `obligatoire=true`. Et à l'inverse `multiple=true` fonctionne [dans la saisie selection](https://git.spip.net/spip-contrib-extensions/saisies/src/branch/master/saisies/selection.html#L42) par exemple, mais `multiple="non"` ne fonctionne pas ! Si c'est pas forcément évident à régler, c'est pas non plus impossible :) Pour normaliser dans toutes les saisies, il faudrait peut-être passer par un filtre `|saisies_booleen` afin d'avoir le même résultat partout. Dans les squelettes pour passer un vrai booléen on peut faire `#EVAL{true}`, mais là c'est plus une question propre à saisies, car on décide d'accepter en plus les pseudos valeurs oui-non pour simplifier. ## Tests J'ai commencé à tester quelques options avec ça (readonly, multiple et obligatoire) : ```php function formulaires_test_booleens_saisies_dist() { // Les valeurs à tester $valeurs = [true, 'oui', false, 'non']; // Les options à tester, et avec quelles saisies $tests = [ 'readonly' => [ 'saisie' => 'input', 'valeurs_erreurs' => [true], ], 'multiple' => [ 'saisie' => 'selection', 'valeurs_erreurs' => ['non'], 'options' => [ 'data' => [ 'bonjour' => 'Bonjour', 'aurevoir' => 'Aurevoir', ], 'cacher_option_intro' => 'oui', ], ], 'obligatoire' => [ 'saisie' => 'input', 'valeurs_erreurs' => [true], ] ]; $saisies = []; foreach ($tests as $option => $stuff) { $saisies_fieldset = []; foreach ($valeurs as $valeur) { $ok = in_array($valeur, $stuff['valeurs_erreurs'], true) ? '❌' : '✅'; $nom_valeur = (is_bool($valeur) ? ($valeur ? 'true' : 'false') : "\"$valeur\""); $saisies_fieldset[] = [ 'saisie' => $stuff['saisie'], 'options' => array_merge($stuff['options'] ?? [], [ 'nom' => "${option}_${valeur}", 'label' => "$ok $nom_valeur", $option => $valeur, ]), ]; } $saisies[] = [ 'saisie' => 'fieldset', 'options' => [ 'nom' => "fieldset_$option", 'label' => $option, ], 'saisies' => $saisies_fieldset, ]; } return $saisies; } ``` ![](https://git.spip.net/attachments/5c629685-8081-4c37-87da-e24d72a2e52e) ## Nomenklatura Un mot sur les 3 options communes à toutes les saisies en passant : on a quand même un beau mélange là :) | attribut html | nom de l'option | |----|----|----| | required | obligatoire | | readonly | readonly | | disabled | disable | Pour une option c'est le vrai nom anglais de l'attribut html (readonly), pour l'autre c'est du français (obligatoire), et pour la dernière c'est de l'anglais mais *pas* le vrai nom de l'attribut (disable sans 'd' à la fin). Tant qu'à faire je propose de prendre en priorité le vrai nom des attributs html, et garder les autres en fallback → `#ENV{required, #ENV{obligatoire}}` etc.
Poster
Owner

Donc ce que je propose, c'est de faire comme ça pour les options communes par exemple :

#SET{obligatoire,#ENV{obligatoire}|saisies_booleen|?{obligatoire,''}}
#SET{readonly,#ENV{readonly}|saisies_booleen|?{readonly,''}}

Avec le filtre correspondant :

/**
 * Transforme des valeurs d'options en vrais booléens
 *
 * On accepte des alias texte 'oui' et 'non'.
 * Autrement on se repose sur ce qui est évalué à true ou false par php.
 * Ainsi, '', null et 0 renvoient false.
 *
 * @param mixed $valeur
 *     'oui' | 'non' | …
 * @return boolean
 */
function saisies_booleen($valeur) : bool {

	// On transforme certaines valeurs textes en vrai booléens
	$alias = [
		'oui' => true,
		'non' => false,
	];
	$bool = $alias[$valeur] ?? !empty($valeur);

	return $bool;
}

Ainsi 'non', '', 0 et null sont évaluées à false
Et toute autre valeur renvoie true.

(je verrais plus tard pour disable car il peut aussi être un array)

Donc ce que je propose, c'est de faire comme ça pour les options communes par exemple : ```html #SET{obligatoire,#ENV{obligatoire}|saisies_booleen|?{obligatoire,''}} #SET{readonly,#ENV{readonly}|saisies_booleen|?{readonly,''}} ``` Avec le filtre correspondant : ```php /** * Transforme des valeurs d'options en vrais booléens * * On accepte des alias texte 'oui' et 'non'. * Autrement on se repose sur ce qui est évalué à true ou false par php. * Ainsi, '', null et 0 renvoient false. * * @param mixed $valeur * 'oui' | 'non' | … * @return boolean */ function saisies_booleen($valeur) : bool { // On transforme certaines valeurs textes en vrai booléens $alias = [ 'oui' => true, 'non' => false, ]; $bool = $alias[$valeur] ?? !empty($valeur); return $bool; } ``` Ainsi `'non'`, `''`, `0` et `null` sont évaluées à `false` Et toute autre valeur renvoie `true`. (je verrais plus tard pour `disable` car il peut aussi être un array)

Pour les changements de nom je sais pas ça dépend. La plupart sont en français par ailleurs, et par ex "obligatoire" n'avait pas de rapport avec un attribut du HTML, c'était avant la diffusion complète du HTML5, c'était un truc fonctionnel et en rapport avec le back et l'ergo : est-ce que c'est interdit d'être vide dans verifier() du CVT + est-ce qu'on ajoute l'indication dans le label, c'est surtout ça plutôt que l'attribut HTML required.

Pour disable en revanche là oui ya aucun sens, d'avoir décidé de mettre en anglais mais pas avec le bon terme directement… je vois pas l'intérêt.

Pour les changements de nom je sais pas ça dépend. La plupart sont en français par ailleurs, et par ex "obligatoire" n'avait pas de rapport avec un attribut du HTML, c'était avant la diffusion complète du HTML5, c'était un truc fonctionnel et en rapport avec le back et l'ergo : est-ce que c'est interdit d'être vide dans verifier() du CVT + est-ce qu'on ajoute l'indication dans le label, c'est surtout ça plutôt que l'attribut HTML required. Pour disable en revanche là oui ya aucun sens, d'avoir décidé de mettre en anglais mais pas avec le bon terme directement… je vois pas l'intérêt.
Poster
Owner

Pour les changements de nom je sais pas ça dépend

Ouais tout compte fait voyons ça plus tard, un sujet à la fois :)

> Pour les changements de nom je sais pas ça dépend Ouais tout compte fait voyons ça plus tard, un sujet à la fois :)
Collaborator

Est-ce qu'on pourrait écrire un filtre style `

function is_true($var) {
	if ($var === true or $var === 'oui') {
    	return true;
    }
}

(no testé, juste une idée comme cela)

Est-ce qu'on pourrait écrire un filtre style ` ``` function is_true($var) { if ($var === true or $var === 'oui') { return true; } } ``` (no testé, juste une idée comme cela)
Collaborator

ah bah desolé, j'avais pas vu ta proposition @tcharlss. Donc on est raccord !

ah bah desolé, j'avais pas vu ta proposition @tcharlss. Donc on est raccord !
Collaborator

Ya pas des 'On' aussi parfois ?

Ya pas des 'On' aussi parfois ?

@JLuc "toute autre valeur renvoie true"

ya que le "non" comme excepption à gérer, le reste c'est plein = true, vide = false comme partout en PHP

@JLuc "toute autre valeur renvoie true" ya que le "non" comme excepption à gérer, le reste c'est plein = true, vide = false comme partout en PHP
Sign in to join this conversation.
No Milestone
No Assignees
5 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.