Formidable PDF : des PDF depuis les réponses

Un plugin pour générer et envoyer des PDF en fonction de réponse aux formulaire Formidable.

Fonctionnalités

Ce plugin fournit des outils pour générer et envoyer des PDF à partir d’une réponse à un formulaire Formidable.

Il s’appuie sur le plugin pdf_version pour générer le PDF.

Il permet d’envoyer automatiquement les emails par PDF lorsque la réponse passe à un certain statut.

Il permet de générer manuellement les PDF et de les télécharger.

Le plugin est fourni avec un modèle de PDF basique, se contentant de lister tous les champs du formulaire avec le contenu de la réponse.

L’intérêt du plugin est de permettre de créer ses propres modèles, en leur donnant suffisamment de souplesse pour être adaptés à plusieurs formulaires.

Exemples de cas d’usage

Quelque cas d’usage pour ce plugin :

  • Un formulaire permettant d’inscrire à un évènement : proposer de générer un bon cadeau
  • Un formulaire permettant de s’inscrire à une formation : générer un PDF d’attestation de participation à la formation
  • Un formulaire permettant de demander un devis : envoyer une version PDF du devis, avec un encadré “Bon pour accord”

Chacun de ces PDF contient plusieurs types de données

  • des données qui varient selon le moment de production du PDF : la date principalement
  • des données qui ne changent pas (par exemple : le logo de la structure, le cachet, etc.);
  • des données qui varient en fonction d’éléments propres à la réponse soumise par l’internaute (par ex. ses nom et prénom);

Ce plugin permet de générer automatiquement des PDF rassemblant ces trois types de données et de les envoyer par courriel aux personnes concernées.

L’intérêt du plugin est de permettre de créer des modèles de PDF, à l’aide des boucles et balises SPIP, tout en permettant de brancher différents formulaires, donc avec des noms de champs potentiellement différent, sur un même modèle PDF.

Par exemple, ce qui dans le PDF correspond au “nom” pourrait, dans un formulaire correspondre au champ input_1, mais dans un autre formulaire, correspondre au champ input_2.

Le plugin fournit un mécanisme permettant de configurer la correspondance entre les champs de formulaire et ce qui est affiché dans le PDF.

Prérequis

Penser à configurer le plugin pdf_version avant toute chose, afin de s’assurer que la génération de PDF fonctionne.

S’assurer que le dossier config/ ne soit pas accessible depuis le web, ce qui est normalement déj déjà le cas sur la plupart des installations SPIP sur serveur Apache.

Modèle de démonstration

Le plugin est fourni avec un modèle d’exemple. Le PDF généré contient :

  • le numéro de la réponse ;
  • le nom de l’internaute, selon la configuration ;
  • l’ensemble des valeurs soumises par l’internaute.

Pour les créatricesteurs de formulaires

Lors de la configuration des traitements formidable, il est proposé un nouveau traitement “Préparer un PDF”. Ce traitement permet ensuite de choisir quel PDF produire, grâce aux modèles fournis par les webmestres.

Après avoir coché les modèles que l’on souhaite utiliser, il faut configurer chacun d’entre deux pour faire correspondre les champs du formulaire avec les champs du modèle.

Exemple

Configuration de la génération de PDF

Nom du fichier

Tout en début de configuration du PDF, il convient de définir comment est construit le nom du PDF. Pour cela, on peut utiliser les raccourcis @@. Ces raccourcis seront remplacée par la valeur correspondante soumise par l’internaute.

Typiquement, si le nom est dans le champ @input_1@ et le prénom dans le champ @input_2@, on peut mettre @input_1@_@input_2@ comme nom de fichier. Ainsi, le PDF pour Camille Durand s’appellera durand_camille.

Pour éviter des soucis, les nom de fichiers sont transformés : passage en minuscule, suppression des diacritiques et des espaces.

Envoi par courriel à l’internaute

Si

  • le traitement “Envoyer un courriel” est activé
  • dans ledit traitement ; l’option “Envoyer un courriel à l’internaute” est cochée ;

alors une option “Envoyer une copie du PDF à l’internaute” est proposée.

Cette copie sera envoyée à l’adresse email de l’internaute. L’envoi a lieu au moment du passage de la réponse à un statut.

Chaque modèle de PDF définit le(s) statut(s) pour l’envoi à l’internaute :

  • soit le modèle de PDF laisse le choix des statuts, auquel cas il convient de cocher les cases qui correspondent aux statuts désirés ;
  • soit le modèle de PDF définit lui-même les statuts provoquant l’envoi à l’internaute, auquel cas les cases sont déjà cochées et ne peuvent pas être décochées.

On peut également modifier le sujet de l’email contenant le PDF, ainsi que le texte du courriel.

Enfin, pour faciliter l’archivage, il est possible de définir une adresse email qui recevrait une copie (en cachée) du courriel.

À noter que l’adresse l’expéditrice de l’attestation sera identique à celle utilisé pour envoyer l’accusé de réception lors de la soumission du formulaire.

Configuration de l’envoi par email

Pour les responsables du suivi des formulaires

Une fois le formulaire configurée, la personne qui suit les réponses soumises au formulaire dispose de plusieurs options pour générer le PDF.

Option 1 : générer un PDF depuis la fiche de réponse

Cette option est surtout utile en phase de test de mise en place.

Dans l’espace privé, à droite de chaque réponse au formulaire formidable, un formulaire permet de générer et télécharger un PDF à partir de la réponse. Si plusieurs modèle de PDF sont disponibles pour le formulaire, il faut choisir le modèle que l’on veut produire.

Par défaut, le PDF est marqué comme spécimen.

Formulaire pour télécharger un PDF

Option 2 : profiter du changement de statut pour envoyer automatiquement le PDF

Pour peu que le traitement ai été correctement configuré (voir supra), le passage de la réponse d’un statut à l’autre provoque, selon le statut en question, l’envoi par email du PDF en question.

Option 3 : envoyer directement le PDF depuis la fiche de réponse

Si le besoin se fait sentir, par exemple si l’internaute a perdu le courriel contenant le PDF, il est possible de renvoyer le PDF depuis la fiche de la réponse, à droite.

Formulaire pour envoyer une attestation

Pour que le formulaire puisse envoyer l’email, il faut bien sûr que l’option d’envoi par email ait été activée lors de la configuration de la génération du formulaire.

Pour les intégrateurtrices : créer un modèle de PDF

Les modèles sont à créer dans un dossier formidable_pdf accessible dans le path de SPIP. Par exemple, dans un dossier formidable_pdf à la racine de squelettes ou d’un dossier de plugin créé pour l’occasion.

Un modèle possède un identifiant technique noté ci-après <slug>. Il possède également un nom humain correspondant à une chaine de langue SPIP <:formidable_pdf:pdf_<attestation_slug>:>.

Ainsi, pour l’attestation dont le <slug> est attestation_participation, il suffit de créer la chaine de langue pdf_attestation_participation dans un fichier lang/formidable_pdf_fr.php pour disposer de la version française du nom du modèle.

Attention certains mots clés sont réservés et ne peuvent pas être utilisé comme <slug>:

  • pdf_type
  • dist (il s’agit du slug du modèle fourni avec le plugin)

Les modèles se composent de 4 fichiers à l’intérieur du dossier formidable_pdf.

  • <slug>.yaml la description du modèle, sous forme de fichier yaml ;
  • <slug>.html squelette construisant le corps du modèle ;
  • <slug>-header.html squelette construisant l’entête du modèle (optionnel) ;
  • <slug>-footer.html squelette construisant le pied du modèle (optionnel).

Le fichier .yaml

Dans <slug>.yaml, se trouve une succession de clés, dont le sens est expliqué ci-dessous.

La clé instituer

Cette clé contient des sous-clés pour effectuer des actions en lien avec le PDF lorsque la réponse change de statut.

Pour l’heure, la seule sous-clé disponible est envoyer_email. Cette sous-clé peut être :

  • soit une chaine quelconque, dans ce cas lors de la configuration du formulaire, l’ensemble des statuts de réponse seront proposés pour l’envoi du pdf ;
  • soit un tableau comprenant la liste des statuts provoquant l’envoi du PDF, auquel cas il ne sera pas possible de choisir les statuts lors de la configuration des traitements du formulaire.

Exemple pour permettre de choisir les statuts, dans le fichier formidable_pdf/dist.yaml livré avec le plugin :

instituer:
  envoyer_email: 'choix'

À l’inverse, pour un PDF correspondant à une attestation, si on utilise le plugin Statut Attestée, on peut forcer l’envoi du PDF lorsque la réponse passe en statut “Attestée”. Le fichier yaml contient alors ces lignes :

instituer:
  envoyer_email: ['attestee']

La clé options

Cette clé contient une liste de saisies permettant de configurer les paramètres qui seront envoyés aux squelettes qui servent pour générer le fichier pdf.

Typiquement, on utilisera une saisie de type champ pour permettre de choisir un ou plusieur champs du formulaire. La valeur que recevra ce champ sera envoyée au squelette.

Exemple dans le fichier formidable_pdf/dist.yaml

options:
  -
    saisie: 'champ'
    options:
      nom: 'nom'
      label: '<:formidable_pdf:pdf_dist_nom:>'
      type_choix: 'selection'
      env: oui
      class: 'select2'
      obligatoire: 'on'

À noter que lorsqu’on permet de choisir plusieurs champs (via l’option multiple), les valeurs des différents champs seront retournées dans un tableau numérique PHP. Charge au squelette d’utiliser ensuite une boucle (DATA) pour itérer sur ces valeurs, ou une fonction de tableau. Les valeurs vides ne sont pas présentes dans le tableau.

Attention les mot-clé suivants sont réservés, aucune saisie ne peut avoir ces noms:

  • filename
  • envoyer_email
  • saisies_par_nom
  • id_formulaires
  • id_formulaires_reponse
  • valeurs

On peut également proposer aux créateurstrices de formulaire de saisir un texte libre (par ex.), en utilisant simplement une saisie textarea. Il est possible, en réalité, d’utiliser n’importe quel saisie, et pas seulement champ.

Cela peut être utile pour par gérer par exemple les cas de champ conditionnés (voire infra).

Les fichiers de squelette

Les 3 squelettes doivent générer une page HTML complète (y compris les squelettes d’entête et de pied), incluant <head> et doctype. Pour assurer la bonne transformation de la page HTML en PDF, il convient :

  • dans l’entête (balise <head>), de faire appel à #INCLURE{fond=pdf_version/inclure/head} ;
  • dans l’entête du squelette principal, d’avoir une balise title donnant le titre du PDF ;
  • à la toute fin de chaque squelette, d’ajouter #FILTRE{liens_absolus};
  • il peut être nécessaire, selon les transformateurs, HTML->PDF d’encoder les images en base64.

Chaque squelette reçoit en paramètre d’environnement (#ENV) les informations suivantes :

  • Dans des sous-casiers de #ENV{reponse} la valeur des réponses correspondantes aux champs configurés. Par exemple pour le modèle dist, nous pourrons accéder à #ENV{reponse/nom}, puisque nous avons créé une saisie champ dans le ficher formidable_pdf/dist.yaml. À ceci s’ajoute :
    • #ENV{reponse/id_formulaire} l’identifiant numérique du formulaire ;
    • #ENV{reponse/id_formulaires_reponse} l’identifiant numérique de la réponse ;
    • #ENV{reponse/valeurs} les valeurs brutes de la réponse, utile notamment si on veut permettre des affichages conditionnel selon la syntaxe afficher_si au sein du squelette (voir infra).
    • #ENV{reponse/saisies_par_nom} la liste des saisies du formulaire et leur configurations, classées par nom ;
  • dans #ENV{date} la date de génération du PDF ;
  • dans #ENV{body_class}, une ou plusieurs classes css supplémentaires applicables au <body>; pour l’heure, le plugin se contente d’ajouter la classe specimen lorsqu’il faut générer un spécimen ; charge à l’intégrateurtrice d’en tirer les conséquences en terme CSS.

Usage avancé : permettre aux créateurstrices de formulaire de donner les conditions pour afficher un champ dans le formulaire

Supposons un gabarit d’attestation permettant d’afficher “Salarié(e) de” dans le PDF. Supposons par ailleurs qu’un même formulaire permette d’inscrire des personnes à la fois salariée et non salariée.

Comment faire pour permettre à ce formulaire d’utiliser ce gabarit en conditionnant l’affichage de la mention “Salarié(e) de” au fait que la personne ait bien indiquée qu’elle était salariée ?

On voudrait permettre à la personne configurant le formulaire d’utiliser la syntaxe des afficher_si du plugin saisies.

Pour ce faire, deux étapes

  1. Dans le .yaml insérer un champ pour stocker l’afficher_si
-
  saisie: 'textarea'
  options:
    nom: 'structure_afficher_si'
    label: '<:saisies:option_afficher_si_label:>'
    explication: '<:saisies:option_afficher_si_explication:>'
    rows: 10
  verifier:
    -
      type: 'afficher_si'
  1. Dans le squelette, interpréter ce champ en fonction des éléments répondus
        [(#ENV**{reponse/structure_afficher_si}|saisies_evaluer_afficher_si{#ENV{reponse/valeurs},#ENV{reponse/saisies_par_nom}}|oui)
            Mettre ici ce qu'on veut afficher si la personne a répondu
           qu'elle était salariée
        ]

Pour les dev PHP

L’essentiel des outils PHP du plugin sont définis sous forme de classe, rangée sous forme arborescente (namespaces), et définie dans le dossier Formidable_pdf avec un fichier par classe.

Inclure le fichier formidable_pdf_autoload.php permet d’activer l’autoloader.

Première approche

L’exemple ci-dessus permet d’envoyer une attestation correspondant à une réponse de formulaire précise. On suppose qu’on a vérifié au préalable que le formulaire permet bien de gérer les attestations.

// Simplifier les appels aux class
use Formidable_pdf\Builder\PdfVersion as Builder;
use Formidable_pdf\Sender\EnvoyerMail;
use Formidable_pdf\SendFromSource\FormulairesReponse as SendFromSource;

// Autoloading
include_spip('Formidable_pdf');

$id_formulaires_reponse = 200;// La réponse 200
$type = 'dist' // le modèle de PDF `dist`
$setting = new Setting(
    $id_formulaires_reponse,
    $type
    );// Le setting va faire les correspondance entre les champs remplis par
    l'internaute et les valeurs envoyés au squelette
$builder = new Builder();//Le builder, c'est ce qui construit concrètement le
PDF
$builder->set($setting);
$send_from_source->addBuilder($builder);
$send_from_source->send(new EnvoyerMail(), $type);//On envoi un type de PDF en
s'appuyant sur la fonction `envoyer_mail()` de spip
$send_from_source = new SendFromSource($id_formulaires_reponse);// Une classe
qui s'occupe d'envoyer à partir d'une réponse de formulaire

Les classes disponibles

Chaque classe est implémentée suivant une Interface précise. Cela permet d’avoir d’autres implémentations selon les outils techniques que l’on veut utiliser.

  • Les classes d’interface Formidable_pdf\Setting\SettingInterface s’occupent pour l’essentiel de construire les paramètres d’environnement à passer au squelette ; une classe est fournie pour régler ces paramètres en fonctions d’une réponse formidable, mais on pourrait en définir une autre pour étendre à d’autres cas que Formidable.
  • Les classes d’interface Formidable_pdf\Builder\BuilderInterface s’occupent d’appeler le générateur de PDF à partir d’un fond / squelettes SPIP. Pour l’instant, on a fourni une classe uniquement pour le plugin version_pdf, mais il existe d’autres plugins transformant du HTML en PDF.
  • Les classes d’interface Formidable_pdf\Sender\SenderInterface permettent d’envoyer l’attestation par email. Il en existe une qui se base sur la fonction envoyer_mail() de SPIP / surchargée par le facteur, mais on pourrait imaginer d’en avoir une pour envoyer les mails via Mailshot (et ainsi avoir une interface montrant tous les mails d’envoi d’attestation).
  • Les classes d’interface Formidable_pdf\SendFromSource\SendFromSourceInterface s’occupent d’aller chercher une source de données pour fabriquer un PDF, puis de construire le(s) PDF (en utilisant une classe d’interface BuilderInterface) et de l’envoyer (en utilisant une classe d’interface SenderInterface).

Remarque sur la génération, le stockage et l’effacement des PDF

Les PDF ne sont pas générés à la soumission du formulaire, mais uniquement lorsque nécessaire (utilisation du formulaire latéral sur les panneaux de réponse, changement de statut de la réponse, etc.).

Ils sont conservés dans le dossier config/formidable/formidable_pdf, rangés par formulaire, puis par réponse, puis par type de PDF. Si jamais la configuration / le gabarit du modèle de PDF est modifié, le PDF n’est pas re-généré.

Les PDFs pouvant contenir des données personnelles, il est important que le dossier config/formidable/formidable_pdf ne soit pas accessible depuis le web.

Si vous utilisez SPIP sur une serveur Apache correctement configuré, SPIP s’occupe automatiquement de ne pas permettre l’accès au dossier config et à ses sous-dossier. Si ce n’est pas le cas, vérifiez votre installation. Si vous utilisez autres choses qu’Apache, vous savez sans doute comment faire.

Afin de limiter les fuites de données,

  • lorsqu’une réponse est effacée de la base de données (soit parce qu’elle était à la poubelle, soit parce que le formulaire est configuré pour effacer régulièrement les réponses), les PDF de la réponse sont effacés ;
  • lorsqu’un formulaire est effacé de la base de donnée (car il était à la corbeille), les PDF des réponses du formulaire sont effacés ;
  • lorsque le traitement “Générer un PDF” est désactivé, les PDF des réponses du formulaire sont effacés ;
  • lorsque certains modèles de PDF ne sont plus proposés à la génération pour un formulaire données, les PDF qui suivent ce modèle pour le formulaire en question sont effacés ;
  • lorsque le plugin est désinstallé (pas désactivé !) les PDFs sont effacés.

Les PDF ne sont PAS effacés si un modèle de formulaire est modifié au niveau du gabarit HTML/YAML, ou si la configuration correspondante est modifiée, etc.

Pour le cas où il faut vraiment effacer certains PDF, le code PHP suivant peut servir

<?php

use Formidable_pdf\Setting\FormulairesReponse;

include_spip('formidable_pdf_autoload');

supprimer_repertoire(FormulairesReponse::getPdfTypeDirectoryPath($type_pdf, $id_formulaires_reponse, $id_formulaire));

La classe Formidable_pdf\Setting\FormulairesReponse possède différente méthodes statiques pour trouver les différents chemins.

  • FormulairesReponse::getPdfTypeDirectoryPath($type_pdf, $id_formulaires_reponse, $id_formulaire) ; pour les chemins d’un type de PDF pour une réponse précise d’un formulaire précis ;
  • FormulairesReponse::getReponseDirectoryPath(, $id_formulaires_reponse, $id_formulaire) pour les chemins d’une réponse précise d’un formulaire précis ;
  • FormulairesReponse::getFormulaireDirectoryPath($id_formulaire) pour les chemins d’une formulaire précis ;
  • ainsi que la constante FormulairesReponse::DIR_PDF pour le chemin du dossier contenant l’ensemble des PDF.

Discussion

No discussion

Add a comment

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.

Who are you?
[Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom