[SPIP] v3.2.1-->v3.2.2
[lhc/web/www.git] / www / ecrire / inc / exporter_csv.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2019 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 /**
14 * Gestion d'export de données au format CSV
15 *
16 * @package SPIP\Core\CSV\Export
17 **/
18
19 if (!defined('_ECRIRE_INC_VERSION')) {
20 return;
21 }
22
23 include_spip('inc/charsets');
24 include_spip('inc/filtres');
25 include_spip('inc/texte');
26
27 /**
28 * Exporter un champ pour un export CSV : pas de retour a la ligne,
29 * et echapper les guillements par des doubles guillemets
30 *
31 * @param string $champ
32 * @return string
33 */
34 function exporter_csv_champ($champ) {
35 #$champ = str_replace("\r", "\n", $champ);
36 #$champ = preg_replace(",[\n]+,ms", "\n", $champ);
37 #$champ = str_replace("\n", ", ", $champ);
38 $champ = preg_replace(',[\s]+,ms', ' ', $champ);
39 $champ = str_replace('"', '""', $champ);
40
41 return '"' . $champ . '"';
42 }
43
44 /**
45 * Exporter une ligne complete au format CSV, avec delimiteur fourni
46 *
47 * @uses exporter_csv_champ()
48 *
49 * @param array $ligne
50 * @param string $delim
51 * @param string|null $importer_charset
52 * Si défini exporte dans le charset indiqué
53 * @return string
54 */
55 function exporter_csv_ligne($ligne, $delim = ', ', $importer_charset = null) {
56 $output = join($delim, array_map('exporter_csv_champ', $ligne)) . "\r\n";
57 if ($importer_charset) {
58 $output = unicode2charset(html2unicode(charset2unicode($output)), $importer_charset);
59 }
60
61 return $output;
62 }
63
64 /**
65 * Exporte une ressource sous forme de fichier CSV
66 *
67 * La ressource peut etre un tableau ou une resource SQL issue d'une requete
68 * L'extension est choisie en fonction du delimiteur :
69 * - si on utilise ',' c'est un vrai csv avec extension csv
70 * - si on utilise ';' ou tabulation c'est pour E*cel, et on exporte en iso-truc, avec une extension .xls
71 *
72 * @uses exporter_csv_ligne()
73 *
74 * @param string $titre
75 * titre utilise pour nommer le fichier
76 * @param array|resource $resource
77 * @param string $delim
78 * delimiteur
79 * @param array $entetes
80 * tableau d'en-tetes pour nommer les colonnes (genere la premiere ligne)
81 * @param bool $envoyer
82 * pour envoyer le fichier exporte (permet le telechargement)
83 * @return string
84 */
85 function inc_exporter_csv_dist($titre, $resource, $delim = ', ', $entetes = null, $envoyer = true) {
86
87 $filename = preg_replace(',[^-_\w]+,', '_', translitteration(textebrut(typo($titre))));
88
89 if ($delim == 'TAB') {
90 $delim = "\t";
91 }
92 if (!in_array($delim, array(',', ';', "\t"))) {
93 $delim = ',';
94 }
95
96 $charset = $GLOBALS['meta']['charset'];
97 $importer_charset = null;
98 if ($delim == ',') {
99 $extension = 'csv';
100 } else {
101 $extension = 'xls';
102 # Excel n'accepte pas l'utf-8 ni les entites html... on transcode tout ce qu'on peut
103 $importer_charset = $charset = 'iso-8859-1';
104 }
105 $filename = "$filename.$extension";
106
107 if ($entetes and is_array($entetes) and count($entetes)) {
108 $output = exporter_csv_ligne($entetes, $delim, $importer_charset);
109 }
110
111 // on passe par un fichier temporaire qui permet de ne pas saturer la memoire
112 // avec les gros exports
113 $fichier = sous_repertoire(_DIR_CACHE, 'export') . $filename;
114 $fp = fopen($fichier, 'w');
115 $length = fwrite($fp, $output);
116
117 while ($row = is_array($resource) ? array_shift($resource) : sql_fetch($resource)) {
118 $output = exporter_csv_ligne($row, $delim, $importer_charset);
119 $length += fwrite($fp, $output);
120 }
121 fclose($fp);
122
123 if ($envoyer) {
124 header("Content-Type: text/comma-separated-values; charset=$charset");
125 header("Content-Disposition: attachment; filename=$filename");
126 //non supporte
127 //Header("Content-Type: text/plain; charset=$charset");
128 header("Content-Length: $length");
129 ob_clean();
130 flush();
131 readfile($fichier);
132 }
133
134 return $fichier;
135 }