Saisies

Le plugin Saisies facilite le développement des formulaires, en proposant des méthodes et outils pour déclarer et vérifier les champs.

Introduction

Créer un formulaire est une tâche toujours un peu répétitive : les champs ont souvent les mêmes propriétés, le même accompagnement (message d’erreur, explication ...) et la même structure HTML. Ce plugin est un outil d’aide au développement, ayant pour but de faciliter et d’accélérer l’écriture des formulaires.

Pour cela, Saisies propose plusieurs mécanismes (balises, API PHP) pour générer et manipuler plus facilement les champs des formulaires. De cette manière, les squelettes de formulaires sont :

  • plus lisibles : il n’y a que le strict nécessaire dedans, pas de répétition ;
  • intégrés au fonctionnement CVT de SPIP, notamment pour la gestion des erreurs sur les champs ;
  • automatiquement compatibles avec les recommandations HTML/CSS de SPIP.

Dans la présente documentation, nous présentons la manière de construire un formulaire avec Saisies de la méthode la plus robuste à la méthode la moins robuste.

Les méthodes moins robustes sont présentées pour deux raisons :

  1. ce sont les méthodes les plus anciennes. On trouve encore beaucoup de code les utilisant ;
  2. il est parfois nécessaire de passer par là, pour des réglages fins.

Pour utiliser l’API complète PHP, vous devez installer ou nécessiter le plugin YAML dans votre plugin. Ce n’est pas le cas quand on utilise juste la simple balise, ce pourquoi c’est à vous de le nécessiter.

Dans la présente documentation, lorsqu’un code est entre chevrons (comme <ceci>), vous devez le remplacer par une valeur correspondant à votre projet.

Cette documentation est valable à partir de la version 4.11.0 ou du plugin.

Méthode 1 : déclarer un formulaire CVT complet en PHP

Principe

Saisies augmente l’API CVT de SPIP avec une fonction formulaires_<nomduformulaire>_saisies() afin de déclarer l’ensemble des champs d’un formulaire et leur vérification dans une unique syntaxe. Cette fonction permet également de déclarer différents réglages de formulaire, tel que :

  • le label du bouton de validation final ;
  • l’utilisation en multiétapes.

Grâce à ce mécanisme, pour les cas les plus courants, les fonctions formulaires_<nomduformulaire>_charger() et formulaires_<nomduformulaire>_verifier() deviennent facultatives. Saisies s’occupera de tout suivant votre déclaration. Seule la fonction formulaires_<nomduformulaire>_traiter() reste toujours de votre ressort.

De même, par défaut, vous n’avez plus à vous occuper du squelette. Il doit toujours être présent, avec le même nom que votre fichier PHP dans le dossier formulaires/, mais vous devez le laisser totalement vide. Saisies s’occupera de générer le HTML complet, en suivant les recommandations de structuration de SPIP.

Enfin, dans le cas particulier où vous créez un formulaire de configuration, vous n’aurez même pas à déclarer les valeurs par défaut ni le traitement. Voir l’article « Formulaire de configuration avec le plugin Saisies ».

Mise en œuvre

Il vous faut donc créer un fichier formulaires/<nomduformulaire>.html vide, ainsi qu’un fichier formulaires/<nomduformulaire>.php contenant deux fonctions :
- formulaires_<nomduformulaire>_traiter(), qui indique ce que votre formulaire doit effectuer comme traitement ; cela n’est pas du ressort du plugin Saisies ;
- formulaires_<nomduformulaire>_saisies(), pour déclarer les saisies proprement dites.

Cette dernière fonction reçoit comme arguments les mêmes arguments que la fonction _charger() du formulaire CVT, et elle doit retourner un tableau PHP contenant la liste de toutes vos saisies suivant un formalisme attendu.

formulaires_<nomduformulaire>_saisies(…) {
    $saisies = […];
    return $saisies;
}

Déclaration de l’ensemble des saisies

Chaque ligne globale du tableau renvoyé décrit une saisie.
L’ordre des éléments sera l’ordre des saisies.

$saisies = [
    […], // une saisie
    […], // une saisie
    […], // une saisie
];

Déclaration d’une saisie individuelle

Chaque saisie est elle-même décrite dans un tableau, qui prend par exemple la forme suivante :

[
    'saisie' => 'input',
    'options' => [
        'nom' => 'nom',
        'label' => 'Votre nom',
        'defaut' => 'Valeur par défaut'
    ],
];

On consultera « Référence des saisies » pour avoir l’ensemble des saisies et des options disponibles en standard.

D’autres plugins ajoutent leurs propres saisies, et vous pouvez aussi créer vos propres saisies.

Déclaration des saisies enfants

Les saisies qui acceptent des enfants (comme les fieldsets) les placent dans une clé saisies dont la valeur est un tableau ayant la même structure que le tableau global :

$un_fieldset = [
    'saisie' => 'fieldset',
    'options' => [
        'nom' => 'mon_groupe',
        'label' => 'Mon groupe de champ'
    ],
    'saisies' => [
        […], // une autre saisie
        […], // une autre saisie
        […], // etc
    ]
];

Appliquer des vérifications

Pour des vérifications simples et uniques vous pouvez en déclarer des vérifications à appliquer sur chacune de vos saisies, avec le plugin API de Vérification (qui n’est pas activé automatiquement avec le plugin saisies).

Il faut alors ajouter une clé verifier selon ce formalisme :

[
	'saisie' => 'input',
	'options' => [
		'nom' => 'slug',
		'label' => 'slug',
		'obligatoire' => 'oui',
	],
	'verifier' => [
		[
			'type' => 'taille',
			'options' => ['min' => 10]
		],
		[
			'type' => 'slug',
		],
	],
];

Permet de vérifier que nous avons affaire à un slug d’une taille minimum de 10 caractères.

Consulter « Références des vérifications » pour la liste des types de vérification livrés avec le plugin et de leurs options.

Pour les versions du plugin < 4.3.0, il n’est possible de déclarer qu’une seule vérification par saisie, sous la forme :
[
    'saisie' => 'input',
    'options' => [
        'nom' => 'nom',
        'label' => 'nom',
        'obligatoire' => 'oui',
    ],
    'verifier' => [
            
        'type' => 'entier',
        'options' => [
            'min' => 100,
            'max' => 500
        ],
    ],
];

Support du multilinguisme

Saisies supporte le multilinguisme. Ainsi, dans l’exemple ci-dessous, la chaine de langue <:cle:valeur:> sera automatiquement interprétée.

[
    'saisie' => 'input',
    'options' => [
        'nom' => 'nom',
        'label' => '<:cle:valeur:>',
        'size' => 50
    ],
];

Options globales

Il est possible de déclarer des options d’affichage globales à l’ensemble du formulaire. Elles sont alors placées dans une clé options à la racine du tableau des saisies.

$saisies = [
    'options' => [
        // Changer l'intitulé du bouton final de validation
        'texte_submit' => 'Valider c’est gagné',
        …
        '<option>' => '<valeur>' //Une autre option
    ],
    […], // une saisie
    […], // une saisie
    […], // une saisie
);
OptionUsageValeur possibleValeur par défaut
Options pour le bouton de validation
texte_submit Texte du bouton de validation Texte, passe par _T_ou_typo() <:bouton_enregistrer:>
afficher_si_submit Condition pour afficher le bouton de validation Voir « Affichage conditionnel des saisies : syntaxe des tests » null
Options pour la gestion des étapes multiples
etapes_activer Activer la gestion multi-étapes, chaque fieldset de premier niveau devient une étape True|False False
etapes_presentation Mode de présentation des étapes en haut du formulaire 'defaut'|'courante', il est possible de créer son propre mode en créant un squelette formulaires/inc-saisies-cvt-etapes-<presentation>.html defaut
etapes_suivant Texte du bouton pour aller à l’étape suivante Texte, passe par _T_ou_typo() <:bouton_suivant:>
etapes_precedent Texte du bouton pour revenir à l’étape précédente Texte, passe par _T_ou_typo() <:precedent|ucfirst:>
etapes_precedent_suivant_titrer Permet d’ajouter le titre des étapes dans les boutons « précédent » et « suivant » True|False False
etapes_ignorer_recapitulatif Permet de ne pas insérer de récapitulatif avant la validation finale True|False False
Options techniques
verifier_valeurs_acceptables Permet de s’assurer que les valeurs reçues figurent bien parmi les valeurs proposées lors de la saisie du formulaire True|False False
afficher_si_avec_post Permet que les saisies masquées par affichage conditionnel soient tout de même postées True|False False
inserer_debut Contenu arbitraire à insérer au début du formulaire, par exemple pour appeler un script Javascript Chaîne de caractères null
inserer_fin Contenu arbitraire à insérer à la fin du formulaire, par exemple pour appeler un script Javascript Chaîne de caractère null

Si un texte passe par _T_ou_typo(), cela peut être :

  • un texte directement écrit dans la langue du site ;
  • un appel à une chaîne de langue sous la forme <:fichier_de_langue:chaine:> ;
  • un texte utilisant la balise <multi> pour gérer l’internationalisation.

Pipeline

Lors du chargement des saisies déclarées via une fonction formulaires_<nom_du_formulaire>_saisies(), les saisies sont passés à un pipeline formulaire_saisies. Le tableau $flux passé à ce pipeline à la structure suivante :

-  $flux['args']['form'] : le nom du formulaire ;
-  $flux['args']['args'] : les différents arguments passés ;
-  $flux['data'] : les saisies.

Il est donc possible à un plugin de modifier dynamiquement les saisies d’un formulaire en utilisant les différentes fonctions de l’API de saisies.

Méthode 1a : déclarer un formulaire CVT en PHP, mais effectuer soi-même des vérifications

Parfois il est nécessaire d’avoir des vérifications supplémentaires sur les saisies. Pour ce faire, vous devez déclarer votre propre fonction formulaires_<nomduformulaire>_verifier().

Dans ce cas, vous ne perdrez pas le bénéfice d’une déclaration des vérifications de base dans votre tableau de saisies : celles-ci sont alors automatiquement effectuées après vos propres vérifications.

Toutefois, il est parfois nécessaire de faire en sorte que les vérifications « par déclaration » se fassent avant vos propres vérifications. Dans ce cas, la méthode la plus propre est de déclarer ses vérifications non pas sous forme d’une fonction formulaires_<nomduformulaire>_verifier(), mais par la création d’une fonction formulaires_<nomduformulaire>_verifier_post_saisie(), ou sa variante verifier_etapes_post_saisies() dans le cadre du multiétape.

À noter qu’il existe deux pipelines pour ajouter des vérifications à un formulaire existant : formulaire_verifier_post_saisies et formulaire_verifier_etapes_post_saisies.

Méthode 1b avec #GENERER_SAISIES : contrôler la structure globale du formulaire, mais utiliser le formalisme de saisies

Dans quelques cas rares, la structure globale du formulaire livrée avec Saisies ne convient pas. Pour autant, vous souhaitez.

  • profiter du formalisme de déclaration des saisies
  • profiter de la vérification automatique de ces saisies (sauf si vous utilisez la méthode 1a).

Dans ce cas :

  • vous mettez dans votre fichier formulaires/<nomduformulaire>.html la structure globale du formulaire correspondant à votre besoin ;
  • là où vous souhaitez insérer vos saisies, vous utilisez la balise #GENERER_SAISIES.

Cette balise permet de générer toutes les saisies d’un formulaire, en une seule fois. Pour cela on lui passe en paramètre le tableau de description.

Exemple d’utilisation :

<div class="formulaire_spip formulaire_#ENV{form}"[(#ENV{_etape}|oui)formulaire_multietapes]">
<form .... [ data-resume_etapes_futures="(#ENV{_resume_etapes_futures}|json_encode|attribut_html)"]>
....
<div >
    #GENERER_SAISIES{#ENV{_saisies}}
</div>
....
</form>
</div>

On notera l’emploi d’un _ en préfixe de la variable d’environnement. Cela permet que les guillemets présents dans les options ne soient pas transformés en entités HTML [1].

#ENV{_saisies} est rempli automatiquement avec la valeur de retour de la fonction formulaires_<nomduformulaire>_saisies() [2].

On n’oubliera pas les attributs suivants :
-  les différentes classes sur le <div> englobant
-  l’attribut [ data-resume_etapes_futures="(#ENV{_resume_etapes_futures}|json_encode|attribut_html)"] sur le <form>, qui permet de gérer correctement les affichages conditionnels des étapes dans un formulaire multi-étape.

Par ailleurs, on utilisera

		[(#ENV{_etape}|oui)
			<INCLURE{fond=formulaires/inc-saisies-cvt-etapes-#ENV{_saisies/options/etapes_presentation,defaut}, etapes=#ENV{_saisies_par_etapes}, env} />
		]
</div>
pour insérer le chemin d'étapes, et 

<cadre class="spip">
<INCLURE{fond=formulaires/inc-saisies-cvt-boutons,env} />

pour les boutons de validation.

Méthode 2 : la balise #SAISIE

Parfois on veut pouvoir contrôler encore plus finement la présentation des saisies. Pour ce faire, on peut insérer dans formulaires/<nomduformulaire>.html des appels à la balise #SAISIE.

Cette méthode n’est pas toujours adaptée, car elle présente des limitations :

  1. elle ne permet pas de profiter des vérifications automatiques ;
  2. elle ne permet pas de profiter du mécanisme d’affichage conditionnel.

#SAISIE permet de générer une seule saisie en lui donnant directement les paramètres désirés. Chaque saisie va générer une ligne dans un formulaire, c’est-à-dire un élément <div>.

La balise #SAISIE a deux arguments obligatoires : le type de saisie, et son nom HTML (attribut « name »). Toutes les autres options sont facultatives et servent à configurer le champ ; de ce fait, elles sont de la forme option=valeur.

La forme complète est donc la suivante :
#SAISIE{type, name, option=valeur, option2=valeur2, etc=etc}

Voici quelques exemples d’utilisation.

Génère un simple champ texte, indiqué comme étant obligatoire :
#SAISIE{input, email, label=Votre courriel, obligatoire=oui}

Génère un choix multiple parmi les utilisateurs du SPIP :
#SAISIE{auteurs, destinataires,
    label=Destinataires du message,
    explication=Choisissez une ou plusieurs personnes à qui sera envoyé le message.,
    multiple=oui}

Comme vous le voyez, des champs qui peuvent être complexes, et fastidieux à écrire de manière complète, s’écrivent ici en quelques lignes.

#SAISIE supporte le multilinguisme. Dans ce cas, attention de bien utiliser la syntaxe complète avec les crochets :

  • #SAISIE{input, annee, label=<:monplugin:annee:>,obligatoire=oui} ne fonctionne pas ;
  • [(#SAISIE{input, annee, label=<:monplugin:annee:>,obligatoire=oui})] fonctionne.

Appendice 1 : chargement des CSS et scripts Javascript sur le site public

Si votre formulaire est destiné à être public, le plugin se charge d’ajouter automatiquement les appels aux fichiers CSS et scripts Javascript associés aux saisies utilisées sur le site public, lorsque le formulaire est effectivement utilisé.forme

Toutefois, si vous avez beaucoup de formulaires utilisant Saisies sur le site public, il peut être judicieux de charger systématiquement les fichiers sur toutes les pages, afin de profiter de la compréhension et du cache navigateur. Dans la configuration du plugin (« Squelettes »->« Configuration du plugin Saisies »), une option permet d’activer cela.

Appendice 2 : enregistrer des tableaux

La norme HTML permet de gérer des réponses de formulaire sous la forme de tableau.

Dans la déclaration de la saisie, on peut utiliser la syntaxe HTML classique avec crochets :

[
    'saisie' => 'input',
    'options' => [
        'nom' => 'annee[debut]',
        'label' => 'Votre nom',
        'size' => 50
    ],
];

Mais il est recommandé d’utiliser le formalisme SPIP suivant : <tableau>/<clé>.

[
    'saisie' => 'input',
    'options' => [
        'nom' => 'annee/debut',
        'label' => 'Label',
        'size' => 50
    ],
];

Le code suivant permettra de récupérer la valeur en PHP :

$annee = _request('annee');
$debut = $annee['debut'];

Appendice 3 : la balise #VOIR_SAISIES

Cette balise permet d’afficher toutes les valeurs saisies après validation d’un formulaire. On lui passe en paramètre deux arguments :

  1. le tableau de description des saisies (au même format que pour #GENERER_SAISIES)
  2. un tableau des valeurs saisies

Exemple d’utilisation, dans le squelette d’un formulaire :

[(#EDITABLE|non)
    #VOIR_SAISIES{#ENV{mes_saisies}, #ENV}
]

Appendice 4 : problème avec Xdebug

Si vous développez en utilisant le logiciel Xdebug, il existe un problème connu : par défaut celui-ci affiche une erreur à partir d’un certain niveau d’imbrication de fonctions PHP (« nesting level » dirait Shakespeare).

Le niveau d’imbrication autorisé par défaut est relativement bas, mais on peut le paramétrer. Vous devez donc ajouter cela dans votre configuration PHP/Xdebug :

[xdebug]
xdebug.max_nesting_level = 200 ou 500 ou plus…

Et hop, ça remarche.

Notes

[2Historiquement, elle pouvait aussi être remplie manuellement en ajoutant une clé _saisies dans le tableau de retour de la fonction formulaires_<nomduformulaire_charger(), toutefois ceci ne permet pas de bénéficier de tous les mécanismes d’automatisme du plugin saisies, et les bugs risquent d’être présents. Ce n’est donc pas une fonctionnalité officiellement supportée et validée.

Voir aussi la doc complémentaire et participative sur le wiki :
Saisies : Doc complémentaire

Discussion

179 discussions

  • Ben c’est juste logique quoi... Saisies ne peut que s’insérer dans le pipeline « formulaire_verifier », qui forcément est appelé après la fonction de base.

    Sinon il faudrait modifier SPIP pour modifier les pipelines : « formulaire_pre_verifier » + « formulaire_post_verifier » et ce pour C, V, et T. Tout comme il y a « pre_edition », « post_edition ».

    Donc tu pourrais plutôt faire ta suggestion en lançant le sujet sur spip-dev, c’est pas idiot du tout !

    Répondre à ce message

  • Hello

    Le problème de vérification des saisies obligatoires non affichées étant en passe d’être résolu, un autre problème voit le jour ;-(

    La vérification de Saisies est effectuée après celle du plugin appelant. L’inverse ne serait-il pas plus logique ? => Saisies s’occupe de vérifier tout ce qui a été défini lors de la définition de chaque saisie, puis l’utilisateur vérifie ses trucs propres à son fonctionnement. J’ai par exemple un champ input qui s’attend à recevoir un entier, l’idéal serait que, quand j’arrive dans ma fonction de vérification, cette vérification soit déjà effectuée...

    Répondre à ce message

  • Bonjour,

    Mon problème est résolu mais peut-être qu’il pourra intéresser du monde ;-)

    Je me suis confronté à un problème avec l’utilisation de 2 champs date dans un même formulaire : dans un premier temps, j’avais déclaré ces 2 champs avec le type « date » dans mes #SAISIE et si mes icônes de datepicker s’affichaient bien, pas d’ouverture de calendrier lors du clic sur l’icone...
    J’ai trouvé la solution en déclarant mon premier champ en « DATE » et mon second en « INPUT »

    Du coup, le code généré par le Jquery ne se charge qu’une seule fois et les 2 champs fonctionnent avec leur datepicker respectif ;-)

    Voici le code :

    [(#SAISIE{date, date_debut, debut_periode, label=Date de début de période,class=date})]
    [(#SAISIE{input, date_fin, fin_periode, label=Date de fin de période,class=date})]

    Répondre à ce message

  • 2

    Bonjour,
    J’utilise Saisies pour faire un formulaire de CFG. Je n’ai pas de problème pour récupérer la valeur d’un champ de type « radio », par exemple, si je crée un champ :

    [(#SAISIE{radio, institut, label=Choix de l'institut de tutelle, defaut=autre,datas=#ARRAY{....}})]

    je peux récupérer la valeur choisie dans un squelette par la balise habituelle de CFG :

    [(#CONFIG{kitcnrs/institut})]

    Par contre, ça se corse avec les champs de type « selecteur_rubrique ». Par exemple, avec un champ :

    [(#SAISIE{selecteur_rubrique, id_rubrique_a_la_une, label=«&nbsp;À la une&nbsp;»})]

    Si j’utilise :

    [(#CONFIG{kitcnrs/id_rubrique_a_la_une)]

    la balise renvoie un tableau. J’ai bien essayé d’utiliser le filtre table_valeur :

    [(#CONFIG{kitcnrs/id_rubrique_a_la_une|table_valeur{0})]

    Mais ça renvoie le type d’objet (article/rubrique) et son identifiant séparés par un pipe. Y aurait-il un moyen pour récupérer la valeur du champ ?

    Merci.

    • Il y a une fonction |picker_selected{rubrique} (par exemple), associée. Ça permet de récupérer un tableau des identifiants du type d’objet mis en paramètre (ici rubrique). Ensuite si yen a qu’un tu prends le premier. [(#CONFIG{truc}|picker_selected{rubrique}|table_valeur{0})] Un truc dans ce genre. Par contre je ne sais plus où se trouve la fonction donc il faut peut-être inclure quelque chose pour l’avoir. C’est un sélecteur qui vient de bonux (et qui est intégré dans SPIP 3 maintenant), c’est pas dans Saisies.

    • ça marche sans qu’il soit nécessaire de faire une inclusion, merci bien.

    Répondre à ce message

  • 2

    Bonjour,
    Après un parcours rapide de la documentation, j’ai l’impression que Saisies ne propose pas de champ pour uploader des fichiers et les supprimer. Est ce que cette fonctionnalité est envisageable ? Merci.

    Répondre à ce message

  • 2

    Bonjour,

    J’ai plusieurs problèmes qui apparaissent dans l’admin avec ce plugin :

    -  Le chargement des images téléchargés dans spip tourne indéfiniment, les images se téléchargent bien malgré tout lorsqu’on actualise la page
    -  La page informations personnelle dans auteurs ne s’affiche plus
    -  Le formulaire mot de passe oublié ne s’affiche plus

    J’ai la dernière version de spip (2.1.11)

    • Ce plugin n’a rien à voir avec tous ces points. D’ailleurs ce plugin ne modifie pas le comportement de SPIP (il ne s’insère dans aucun de ses points d’entrée) et n’ajoute aucune page. C’est un outil pour développeur qui ajoute de nouvelles fonctions.

      Qu’est-ce qui fait dire que c’est ce plugin précisément qui provoque ça ? As-tu désactivé TOUS les plugins pour ne tester que l’activation/désactivation de celui là ?

    • En effet je me suis trompé, c’est le plugin afficher objet qui pose ce problème. Désolé.

    Répondre à ce message

  • 8

    Bonjour,
    Je tente d’ajouter un champ date comportant un datepicker avec SAISIE.
    Quand je mets :

    [(#SAISIE{input, date_echeance,
    label=<:kaye:label_date_echeance:>,
    class=date})]

    le champ est fonctionnel mais il n’y a pas le date picker.

    Quand je mets :

    		[(#SAISIE{date, date_echeance,
    			label=<:kaye:label_date_echeance:>,
    			class=date})]	

    il y a bien le date picker mais celui-ci réinitialise la date (0000-00-00)

    dans la table de bdd le champ est de type date (0000-00-00)

    Que dois-je faire pour que ça fonctionne ?

    Merci pour votre aide

    • Chez-moi-ça-marche ©.

      Sans exemple concret (URL ?) je ne vois pas comment aider.

    • Ok donc comment prévu, ni le datepicker, ni le plugin Saisies n’ont rien à voir là-dedans. Ce n’est d’ailleurs même pas lui qui met la date. C’est vous qui dites quoi mettre comme valeur dans votre fonction charger() du CVT. Donc à vous d’aller chercher la bonne valeur et de la formater dans le bon sens (vu que le datepicker est en format français alors qu’en base ça sera en format SQL).

      Donc faut aller chercher votre date, transformer la version SQL en version français jj/mm/aaaa, et la mettre dans le contexte de charger() : $contexte['date_echeance'] = ...; et inversement dans le traiter() il faut retransformer le date FR en date SQL pour l’enregistrer en base.

    • Merci beaucoup pour ces précisions. Je vais creuser cette piste.
      Si je n’y parviens pas, il me suffirait donc de changer, dans la bdd, le type du champ date_echeance, pour passer de DATE à VARCHAR ?
      Encore merci pour votre aide et bonne continuation dans vos projets.

    • J’ai été accidentellement confronté au même problème et je précise :
      -  on peut bien mettre une date par défaut (sinon il n’y a rien, ce qui équivaut à 0000-00-00 en bdd) et cette date par défaut peut être au format ISO-8601 ! ainsi, dans ma fonction charger(), un 'date_echeance'=>date('Y-m-d') renvoie positionne bien la date sur aujourd’hui (affiché 29/08/2011) \o/
      -  mais mon vérifier() —qui s’assure que d’une part la date est au format ISO-8601 et qu’elle est valide met systématiquement le champ en erreur (et donc sans ça, la date qui arrive en bdd est incorrecte, ce qui équivaut à 0000-00-00 pour MySql)  ;-( il faut donc, au niveau du traiter(), le retraiter... (chez moi, sans revérification, c’est : $parts_date_echeance=explode('/',_request('date_echeance')); $bonne_date_echeance=parts_date_echeance[2].'-'.parts_date_echeance[1].'-'.parts_date_echeance[0]; ce qui est bien entendu une façon de faire parmi d’autres)

    • Oui, la fonction verifier() doit faire son travail de vérification avec la valeur de la saisie en « / ». Il y a d’ailleurs une fonction du plugin Vérifier pour ça. Et ensuite au dernier moment il faut transformer la date pour la mettre au format ISO. On peut utiliser un preg_replace() en une fois, ça va plus vite. Ou bien utiliser les fonctions de date de PHP pour transformer la date en « / » en timestamp qu’on retransforme en date ISO ensuite.

    • Merci pour la confirmation RastaPopoulos.

      Le preg_replace() pour transformer une date-fr en date-iso serait du genre :
      $date_echeance = preg_replace('$(0?[1-9]|[1-2][0-9]|3[0-1])/(0?[1-9]|1[0-2])/([1-3][0-9]{3,3})$','\\3-\\2-\\1',$date_echeance);
      _ Mais j’évite d’utiliser les regex quand on peut faire simplement sans... Je ne suis pas certain que ce sois plus rapide (que le str_replace() par exemple dans les cas simples), et par contre ils utilisent plus de ressources matérielles (processeur et mémoire)  :-S
      _ Cependant, si on doit utiliser les regex PCRE/Perl, autant en profiter un max (code non teste) :
      $date_echeance = preg_replace('$[\d{1,2}][\W]+[\d{1,2}][\W]+[\d{1.4}]$','\\5-\\3-\\1',$date_echeance);
      Pour la fonction PHP transformant les dates en « / » en timestamp, si tu as une piste je veux bien la noter dans un coin parce-que je ne connais que strtotime() qui hélas n’accepte que les dates en anglais... (et 03/08/2002 par exemple, est le 8 mars en anglais, et le 3 aout en français...)  :-( ou ISO... Dommage car, un coup de $date_echeance = date('Y-m-d',strtotime($date_echeance)); et ça roulerait

      Pour la vérification, le plugin verifier dispose bien d’une fonction verifer_date_dist qui prend les date-fr et s’assure que le nombre de jours est compris entre 1 et 31 et le nombre du mois entre 1 et 12. (Il me semble aussi qu’il y avait une limitation sur l’année, mais elle n’avait de sens —a mon avis— que pour les dates de naissance...)
      N’utilisant pas ce plugin, je décompose la date comme déjà mentionne et la passe a checkdate() (qui fait les mêmes vérifications sans la limitation d’année, et en prime vérifie la concordance entre des fins de mois —du coup on a ure erreur pour le 30 février par exemple) :

      $parts_date_echeance = explode('/',_request('date_echeance'));
      if ( !checkdate($parts_date_echeance[1],$parts_date_echeance[0],$parts_date_echeance[2]) ) $erreurs['date_echeance'] = _T('date_invalide');

      (c’est bien entendu une méthode parmi d’autres, et elle peut avoir des variantes comme utiliser trois variables chaine au lieu d’une variable tableau :

       list($jour_echeance,$mois_echeance,$annee_echeance) = explode('/',_request('date_echeance'));
      if ( !checkdate($mois_echeance,$jour_echeance,$annee_echeance) ) $erreurs['date_echeance'] = _T('date_invalide');
    • Le plugin Vérifier n’a aucune limitation d’année, et fait bien un checkdate : http://zone.spip.org/trac/spip-zone/browser/_plugins_/verifier/verifier/date.php

      Pour le preg_replace c’était surtout pour la lisibilité, et comme c’est après avoir déjà vérifié que c’était le bon format, t’as pas à tester le format exact, etc, ya juste à changer l’ordre.

      preg_replace('|([\d]+)/([\d]+)/([\d]+)|', '$3-$2-$1', $date)

      Ceci dit ça fait un certain temps qu’on réfléchit à ce que le plugin Vérifier sache aussi formater des données en sortie, après vérification. Exemple qu’on puisse vérifier la validité d’une date qui peut être dans plusieurs formats, mais par contre qu’en sortie on est toujours du ISO. Ou que pour un nom de famille tout soit mis en majuscule sans accent, si le système en a besoin, etc. Ce genre de transformation post-vérification.

    • Cool ça ; ça fait un bout de temps que j’avais pas retesté. En plus c’est un peu comme j’avais commencé à écrire ma fonction de vérification (sauf que j’avais listé les six combinaisons possibles —jma, jam, mja, maj, amj, ajm— et que j’étais iso par défaut)
      Par contre, ce n’est pas une mauvaise chose de pouvoir poser des bornes sur les dates (par exemple site pour ados refusant donc plus d’un certain âge, ou site nécessitant un âge minimum, ou une combinaison des deux), à condition que cela reste optionnel...

      Dans le cas présent (testé avant de poster hier), ça servirait à rien de renvoyer une sortie ISO : le champ date l’accepte, mais le reconverti au format FR !  :-( D’un autre côté, bien que l’idée de formatage soit séduisante, on s’éloigne de la simple vérification et on fait du traitement de présentation...
      Je pense que c’est aux DatePicker de permettre de faire une saisie suivant le format local de l’usager (donc jj/mm/aaaa pour une interface en français, mais mm/jj/aaa pour une interface en anglais) mais de renvoyer la valeur dans un format standard (ici ISO), comme le prévoit HTML5 justement pour les nouveaux champs date, datetime, time.
      À suivre...

      Cédric, j’espère que tu ne l’as pas fait : un VARCHAR (un CHAR est mieux vu que la taille est fixe...) ne sera pas forcément plus économique en place occupée et ça ne change rien au problème puisqu’il faudra quand même que tu stocke au format ISO qui est justement indépendant (pratique pour l’internationalisation et la portabilité) et offre un certain nombre d’avantage (les algorithmes de comparaison et le tri sont plus simples, de plus on sait facilement les convertir vers d’autres formats que l’inverse)

    Répondre à ce message

  • 2
    audwill

    bonjour,

    sur un site spip2.0.12 + ecran de secu
    la mise à jour du plugin Interfaces de champs extra « Nécessite le plugin SAISIES en version [1.13.0 ;] minimum. »
    Or en mettant à jour le plugin saisies ça plante le site (écran blanc en back et frontoffice). En enlevant le dossier du plugin par ftp le site se réaffiche normalement.
    La version antérieure du plugin saisies 1.8.12 [43285] ne plante pas le site... mais ne permet pas d’installer Interfaces pour champs extra.

    merci de votre aide,

    • Bonjour Audwill,

      Un écran blanc est souvent le signe d’une erreur PHP non affichée (ce qui est par défaut le cas de PHP maintenant). Il serait bien, le temps de tester, de faire afficher les erreurs PHP de la sorte, en ajoutant ce code dans ton fichier config/mes_options.php :

      // afficher toutes les erreurs
      error_reporting(E_ALL);
      @ini_set("display_errors", "On");

      Une fois fait, en remettant le plugin saisies et interfaces, devrait logiquement apparaître l’erreur bloquante que tu pourras nous transmettre ici, ce qui nous aidera à comprendre ce qui se passe.

      Merci bien.

    • audwill

      Salut,
      et merci pour ta réponse !

      J’ai copié le bout de code dans config/mes_options.php :

      <?php
      // afficher toutes les erreurs
      error_reporting(E_ALL);
      @ini_set("display_errors", "On");
      ?>

      et réactivé le plugin saisies mais... j’ai toujours une page blanche sans affichage d’erreur php.

      Je supprime ensuite le dossier du plugin via ftp pour que le site s’affiche à nouveau. et là en backoffice j’ai cette indication :
      Erreur dans les plugins : plugins/auto/saisies/saisies_options.php, plugins/auto/saisies/balise/saisie.php, plugins/auto/saisies/inc/saisies.php, plugins/auto/saisies/saisies_pipelines.php (indication qui disparait quand je vide le cache à nouveau).

      que puis-je faire d’autre pour vous donner plus d’infos ?

    Répondre à ce message

  • 4

    Yo

    spip.php ?page=saisie.css surcharge une de mes css coté site public. Voir ici le vilain cadre bleu sur la recherche en haut à gauche. J’ai trouvé saisies.css.html à la racine du répertoire du plugin, toutefois cette css ne comporte pas les class du formulaire de recherche. Comment cela fonctionne-t-il ? Comment retrouver ces class et y apporter des surcharges ?

    • Je ne sais absolument pas d’où ça sort. C’est pas dans une des inclusions du fichier ? Pfff, j’ai jamais voulu ça moi (cherchez le coupable).

    • Ouais voilà, ya quelqu’un qui a ajouté les styles PRIVÉS de bonux à cette CSS, pour utiliser le sélecteur d’articles/rubriques. Mais du coup ça style d’autres choses, aussi, c’est pourri.

      Il faudrait ajouter ça seulement si on est dans la partie privée, mais c’est pas super non plus car on peut très bien vouloir ce sélecteur dans la partie publique aussi. Faudra demander à Yffic.

    • Oui, c’est effectivement ennuyeux. J’ai modifié mon css pour que celui de saisies soit surchargé. Nombreux sont les plugins à gonfler les pages avec des css ou des .js sans que l’on en ai systématiquement besoin. Sur un site comme celui là où prêt de 30 plugins sont couramment utilisés, ça fait vite beaucoup de poids pour rien.

    • Ben non ça fait pas beaucoup de poids puisque de toute façon toutes les CSS d’un même media=truc sont concaténées + compressées et donc envoyées en un seul fichier au client, qui ensuite l’aura en cache. Donc c’est pas le problème le plus chiant.

      Là c’est surtout que ça ajoute des styles très « génériques » sans qu’on s’en aperçoivent, et qui en plus sont au départ réservés uniquement à la partie privée, et c’est vraiment n’importe quoi...

    Répondre à ce message

  • 7

    J’ai un formulaire qui fonctionne bien en utilisant #GENERER_SAISIES.
    Il est dans le répertoire formulaires d’un plugin et appelé dans un article par

    <formulaire|monformulaire>

    Si j’essaye de mettre certains champs dans un ’fieldset’ le formulaire ne s’affiche plus, sans message d’erreur, ni log.
    Pour tester en étant certain d’éliminer les typos, j’ai installé les fichiers film.html et film.php de cet article : http://www.spip-contrib.net/Un-formulaire-C-V-T-avec-Saisies-par-l-exemple dans le répertoire formulaires du plugin et j’appelle ce formulaire dans un article par

    <formulaire|film>

    Même problème, qui disparait si je supprime le fieldset (en laissant les saisies du fieldset).
    C’est déjà arrivé à quelqu’un ? Une idée ?

    • C’est tout le formulaire qui ne s’affiche pas ou juste les saisies contenues dans le fieldset ?

    • Tout le formulaire. Et ça semble stopper les calculs de spip :
      Du coté public, ça affiche l’en-tête et le début (titre, auteur,...) mais pas de pied de page ni de colonne extra.
      Coté privé la tentative d’édition de l’article du coté backend me renvoie ce code en tout et pour tout comme page html : (« formulaire ici », à la fin, est le texte de l’article avant le tag formulaire)

      <div class="champ contenu_surtitre vide">
      <div class='label'>Sur-titre</div>
      <div dir='ltr' class='crayon article-surtitre-9 surtitre'></div>
      </div>
      <div class="champ contenu_titre">
      <div class='label'>Titre :</div>
      <div dir='ltr' class='crayon article-titre-9 titre'>test formulaire bis</div>
      </div>
      <div class="champ contenu_soustitre vide">
      <div class='label'>Sous-titre</div>
      <div dir='ltr' class='crayon article-soustitre-9 soustitre'></div>
      </div>
      <div class="champ contenu_descriptif vide">
      
      <div class='label'>Descriptif :</div>
      <div dir='ltr' class='crayon article-descriptif-9 descriptif'></div>
      </div>
      <div class="champ contenu_chapo vide">
      <div class='label'>Chapeau</div>
      <div dir='ltr' class='crayon article-chapo-9 chapo'></div>
      </div>
      <div class="champ contenu_nom_site vide">
      <div class='label'>VOIR EN LIGNE :</div>
      <div dir='ltr' class='crayon article-hyperlien-9 nom_site'></div>
      </div>
      <div class="champ contenu_texte">
      <div class='label'>Texte</div>
      
      <div dir='ltr' class='crayon article-texte-9 texte'><p>formulaire ici&nbsp;:</p>
      <div>

      Si ça peut aider, c’est un SPIP 2.1.10 [17657] + images(1.0.1), msie_compat(1.0), porte_plume(1.7.8), safehtml(1.3.7), vertebres(1.0), verifier(0.1.9), cfg(1.16.0), crayons(1.9.4), skeleditor(2.5.3), spip_bonux(2.2.21), z(1.7.9), compositions(1.2.3), saisies(1.9.9), compresseur(1.0.1)

    • Chez-moi-ça-marche. ©

      Si c’est tout le formulaire et même apparemment toute la page entière qui est bloquée, c’est forcément qu’il y a une erreur PHP quelque part qui arrête tout.

      Mais sans code sous les yeux, je vais pas pouvoir aider.

    • Hélas, le code est celui de l’article d’exemple...
      Il ne marche pas chez moi.
      Les particularités par rapport à l’exemple :
      -  Les fichiers sont dans le répertoire formulaires d’un plugin.
      -  C’est un site qui fait partie d’une mutualisation.

      Pas d’idée ?

    • J’ai reproduit en installant un spip neuf avec un spip_loader.php downloadé aujourd’hui et les plugins bonux vérifier et saisies à jour de svn ://zone.spip.org/spip-zone/_plugins_ :

      Date	Sun, 12 Jun 2011 16:20:59 GMT
      Server	Apache/2.2.16 (Ubuntu)
      X-Powered-By	PHP/5.3.3-1ubuntu9.5
      Vary	Cookie,Accept-Encoding
      Composed-By	SPIP 2.1.10 @ www.spip.net + images(1.0.1), msie_compat(1.0), porte_plume(1.7.8), safehtml(1.3.7), vertebres(1.0), verifier(0.1.9), spip_bonux(2.2.21), saisies(1.9.9), compresseur(1.0.1)

      Le code de l’exemple ne fonctionne pas. Le même en supprimant les fieldset fonctionne.

    • Ben je te dis que si tout s’arrête c’est qu’il y a une erreur PHP. Si tu fais un site en local, en mode « développement », tu DOIS activer l’affichage des erreurs PHP, sinon tu ne risques pas de pouvoir tester grand chose.

      Le code que tu m’indiques à une parenthèse en trop à la fin... :)

    • RÉSOLU

      Merci pour ton aide !
      en ajoutant

      error_reporting(E_ALL^E_NOTICE);
      ini_set('display_errors',1);

      ça m’a permis de voir que le problème était dû à l’absence du plugin YAML.
      Une fois ce plugin installé tout fonctionne correctement (non, il n’y a pas de parenthèse en trop dans le code d’exemple)

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom