e81f7780663e307a9921b602a58f6e7bdb5cd226
[lhc/web/www.git] / www / plugins / formidable / formulaires / exporter_formulaire_reponses.php
1 <?php
2
3 // Sécurité
4 if (!defined('_ECRIRE_INC_VERSION')) {
5 return;
6 }
7
8 include_spip('inc/formidable');
9 include_spip('inc/formidable_fichiers');
10 include_spip('inc/config');
11
12 function formulaires_exporter_formulaire_reponses_charger($id_formulaire = 0) {
13 $contexte = array();
14 $contexte['id_formulaire'] = intval($id_formulaire);
15
16 return $contexte;
17 }
18
19 function formulaires_exporter_formulaire_reponses_verifier($id_formulaire = 0) {
20 $erreurs = array();
21
22 if (_request('date_debut') && _request('date_fin')) {
23 // Vérifions que la date debut soit < date de fin
24 if (strtotime(str_replace('/', '-', _request('date_debut'))) > strtotime(str_replace('/', '-', _request('date_fin')))) {
25 $erreurs['message_erreur'] = _T('formidable:exporter_formulaire_date_erreur');
26 }
27 }
28
29 return $erreurs;
30 }
31
32 function formulaires_exporter_formulaire_reponses_traiter($id_formulaire = 0) {
33 $retours = array();
34 $statut_reponses = _request('statut_reponses');
35 // Normaliser la date
36 $verifier = charger_fonction('verifier', 'inc/');
37 $verifier(_request('date_debut'), 'date', array('normaliser' => 'datetime'), $date_debut);
38 $verifier(_request('date_fin'), 'date', array('normaliser' => 'datetime'), $date_fin);
39
40 if (_request('type_export') == 'csv') {
41 $ok = exporter_formulaires_reponses($id_formulaire, ',', $statut_reponses, $date_debut, $date_fin);
42 } elseif (_request('type_export') == 'xls') {
43 $ok = exporter_formulaires_reponses($id_formulaire, 'TAB', $statut_reponses, $date_debut, $date_fin);
44 }
45
46 if (!$ok) {
47 $retours['editable'] = 1;
48 $retours['message_erreur'] = _T('formidable:info_aucune_reponse');
49 }
50
51 return $retours;
52 }
53
54 /*
55 * Exporter toutes les réponses d'un formulaire (anciennement action/exporter_formulaire_reponses)
56 * @param integer $id_formulaire
57 * @return unknown_type
58 */
59 function exporter_formulaires_reponses($id_formulaire, $delim = ',', $statut_reponses = 'publie', $date_debut = '', $date_fin = '') {
60 include_spip('inc/puce_statut');
61 // on ne fait des choses seulements si le formulaire existe et qu'il a des enregistrements
62 if ($id_formulaire > 0
63 and $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = ' . $id_formulaire)
64 and $reponses = sql_allfetsel(
65 '*',
66 'spip_formulaires_reponses',
67 'id_formulaire = ' . intval($id_formulaire) . ($statut_reponses == 'publie' ? ' and statut = "publie"' : '')
68 . (strlen($date_debut) > 0 ? ' and date >= "'. $date_debut. '"' : '')
69 . (strlen($date_fin) > 0 ? ' and date <= "'.$date_fin.'"' : '')
70 )) {
71
72 include_spip('inc/saisies');
73 include_spip('facteur_fonctions');
74 include_spip('inc/filtres');
75 $reponses_completes = array();
76
77 // La première ligne des titres
78 $titres = array(
79 _T('formidable:id_formulaires_reponse'),
80 _T('public:date'),
81 _T('formidable:reponses_auteur'),
82 _T('formidable:reponses_ip'),
83 );
84 if ($statut_reponses != 'publie') {
85 $titres[] = _T('formidable:reponse_statut');
86 }
87
88 $saisies = saisies_lister_par_nom(unserialize($formulaire['saisies']), false);
89 foreach ($saisies as $nom => $saisie) {
90 if ($saisie['saisie'] != 'explication') { // on exporte tous les champs sauf explications
91 $options = $saisie['options'];
92 $titres[] = sinon(
93 isset($options['label_case']) ? $options['label_case'] : '',
94 sinon(
95 isset($options['label']) ? $options['label'] : '',
96 $nom
97 )
98 );
99 }
100 }
101
102 // On passe la ligne des titres de colonnes dans un pipeline
103 $titres = pipeline(
104 'formidable_exporter_formulaire_reponses_titres',
105 array(
106 'args' => array('id_formulaire' => $id_formulaire, 'formulaire' => $formulaire),
107 'data' => $titres,
108 )
109 );
110
111 $reponses_completes[] = $titres;
112 $saisies_fichiers = array();
113
114 // sélectionner tous les auteurs d’un coup. Évite N requetes SQL…
115 $ids_auteurs = array_filter(array_map('intval', array_column($reponses, 'id_auteur')));
116 $auteurs = sql_allfetsel('id_auteur, nom', 'spip_auteurs', sql_in('id_auteur', $ids_auteurs));
117 $auteurs = array_column($auteurs, 'nom', 'id_auteur');
118
119 // Sélectionner toutes valeurs des réponses d’un coup. Éviten N requetes SQL...
120 $ids_reponses = array_column($reponses, 'id_formulaires_reponse');
121 $_reponses_valeurs = sql_allfetsel(
122 'id_formulaires_reponse, nom, valeur',
123 'spip_formulaires_reponses_champs',
124 array(
125 sql_in('id_formulaires_reponse', $ids_reponses),
126 //sql_in('nom', array_keys($saisies)) // ralentit la requête, et inutile
127 ),
128 '',
129 'id_formulaires_reponse ASC'
130 );
131
132 // grouper par identifiant de réponse
133 $reponses_valeurs = array();
134 foreach ($_reponses_valeurs as $r) {
135 if (empty($reponses_valeurs[$r['id_formulaires_reponse']])) {
136 $reponses_valeurs[$r['id_formulaires_reponse']] = array();
137 }
138 $reponses_valeurs[$r['id_formulaires_reponse']][$r['nom']] = $r['valeur'];
139 }
140 unset($_reponses_valeurs);
141
142 // Ensuite tous les champs
143 $tenter_unserialize = charger_fonction('tenter_unserialize', 'filtre/');
144
145 // On parcourt chaque réponse
146 foreach ($reponses as $i => $reponse) {
147 // Est-ce qu'il y a un auteur avec un nom
148 $nom_auteur = '';
149 if ($id_auteur = intval($reponse['id_auteur'])) {
150 $nom_auteur = !empty($auteurs[$id_auteur]) ? $auteurs[$id_auteur] : '';
151 }
152
153 // Le début de la réponse avec les infos (date, auteur, etc)
154 $reponse_complete = array(
155 $reponse['id_formulaires_reponse'],
156 $reponse['date'],
157 $nom_auteur,
158 $reponse['ip'],
159 );
160 if ($statut_reponses != 'publie') {
161 $reponse_complete[] = statut_texte_instituer('formulaires_reponse', $reponse['statut']);
162 }
163
164 // Liste de toutes les valeurs
165 $valeurs = $reponses_valeurs[$reponse['id_formulaires_reponse']];
166
167 foreach ($saisies as $nom => $saisie) {
168 if ($saisie['saisie'] != 'explication') {
169
170 // Saisie de type fichier ?
171 if ($saisie['saisie'] == 'fichiers') {
172 $_valeurs = $tenter_unserialize($valeurs[$nom]);
173 //tester s'il y a des saisies parmi les fichiers
174 if (is_array($_valeurs) and $_valeurs) {
175 $chemin = _DIR_FICHIERS_FORMIDABLE . 'formulaire_' . $id_formulaire . '/reponse_' . $reponse['id_formulaires_reponse'];
176 foreach ($_valeurs as $v) {
177 $chemin_fichier = $chemin . '/' . $saisie['options']['nom'] . '/' . $v['nom'];
178 if (file_exists($chemin_fichier)) {
179 $saisies_fichiers[] = $chemin_fichier;
180 }
181 }
182 }
183 }
184
185 $valeur = isset($valeurs[$nom]) ? $valeurs[$nom] : '';
186 $reponse_complete[] = formidable_generer_valeur_texte_saisie($valeur, $saisie);
187 }
188 }
189
190 // On passe la ligne de réponse dans un pipeline
191 $reponse_complete = pipeline(
192 'formidable_exporter_formulaire_reponses_reponse',
193 array(
194 'args' => array(
195 'id_formulaire' => $id_formulaire,
196 'formulaire' => $formulaire,
197 'reponse' => $reponse,
198 ),
199 'data' => $reponse_complete,
200 )
201 );
202
203 // On ajoute la ligne à l'ensemble des réponses
204 $reponses_completes[] = $reponse_complete;
205 }
206
207 if (!count($saisies_fichiers)) {// si pas de saisie fichiers, on envoie directement le csv
208 if ($reponses_completes and $exporter_csv = charger_fonction('exporter_csv', 'inc/', true)) {
209 $exporter_csv('reponses-formulaire-' . $formulaire['identifiant'], $reponses_completes, $delim);
210 exit();
211 }
212 } else {
213 if ($reponses_completes and $exporter_csv = charger_fonction('exporter_csv', 'inc/', true)) {
214 $fichier_csv = $exporter_csv('reponses-formulaire-' . $formulaire['identifiant'], $reponses_completes, $delim, null, false);
215 $fichier_zip = sous_repertoire(_DIR_CACHE, 'export') . 'reponses-formulaire-' . $formulaire['identifiant'] . '.zip';
216 include_spip('inc/formidable_fichiers');
217 $fichier_zip = formidable_zipper_reponses_formulaire($formulaire['id_formulaire'], $fichier_zip, $fichier_csv, $saisies_fichiers);
218 if (!$fichier_zip) {// si erreur lors du zippage
219 return false;
220 } else {
221 formidable_retourner_fichier($fichier_zip, basename($fichier_zip));
222 }
223 }
224 }
225 } else {
226 return false;
227 }
228 }
229
230 /**
231 * Cette fonction retourne le texte d’une réponse pour un type de saisie donnée.
232 *
233 * On limite les calculs lorsque 2 valeurs/types de saisies sont identiques
234 * de fois de suite.
235 *
236 * @param string $valeur
237 * @param array $saisie
238 * @return string
239 */
240 function formidable_generer_valeur_texte_saisie($valeur, $saisie) {
241 static $resultats = array();
242 static $tenter_unserialize = null;
243 if (is_null($tenter_unserialize)) {
244 $tenter_unserialize = charger_fonction('tenter_unserialize', 'filtre/');
245 }
246
247 $hash = md5($saisie['saisie'] . ':' . serialize($saisie['options']) . ':' . $valeur);
248
249 if (!isset($resultats[$hash])) {
250 $valeur = $tenter_unserialize($valeur);
251 // Il faut éviter de passer par là… ça prend du temps…
252 $resultats[$hash] = facteur_mail_html2text(
253 recuperer_fond(
254 'saisies-vues/_base',
255 array_merge(
256 array(
257 'valeur_uniquement' => 'oui',
258 'type_saisie' => $saisie['saisie'],
259 'valeur' => $valeur,
260 ),
261 $saisie['options']
262 )
263 )
264 );
265
266 }
267
268 return $resultats[$hash];
269 }