PluginProbe ʕ •ᴥ•ʔ
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / trunk
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel vtrunk
trunk 0.9.0 0.9.1 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.14 1.4.15 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0
wp-all-export / src / Csv / CsvRfcUtils.php
wp-all-export / src / Csv Last commit date
CsvRcfWriter.php 8 years ago CsvRfcUtils.php 4 weeks ago CsvRfcWriteStreamFilter.php 8 years ago CsvWriter.php 5 months ago
CsvRfcUtils.php
216 lines
1 <?php
2
3 /*
4 * AJGL CSV RFC Component
5 *
6 * Copyright (C) Antonio J. García Lagar <aj@garcialagar.es>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Wpae\Csv;
13
14 /**
15 * @author Antonio J. García Lagar <aj@garcialagar.es>
16 */
17 class CsvRfcUtils
18 {
19 const EOL_WRITE_DEFAULT = "\n";
20 const EOL_WRITE_RFC = "\r\n";
21
22 private static $defaultEol = self::EOL_WRITE_DEFAULT;
23
24 private function __construct()
25 {
26 }
27
28 /**
29 * @see http://php.net/manual/en/function.fputcsv.php
30 *
31 * @param resource $handle
32 * @param array $fields
33 * @param string $delimiter
34 * @param string $enclosure
35 * @param string $escape
36 * @param string $eol
37 */
38 public static function fPutCsv($handle, array $fields, $delimiter = ',', $enclosure = '"', $escape = '\\', $eol = null)
39 {
40 self::checkPutCsvEscape($escape);
41
42 $eol = self::resolveEol($eol);
43 if ($eol !== self::EOL_WRITE_DEFAULT || self::hasAnyValueWithEscapeFollowedByEnclosure($fields, $enclosure)) {
44 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- export plugin reads/writes its own files in uploads dir, WP_Filesystem not viable for streamed CSV/XML output
45 \fwrite($handle, self::strPutCsv($fields, $delimiter, $enclosure, $eol));
46 } else {
47 \fputcsv($handle, $fields, $delimiter, $enclosure, '\\');
48 }
49 }
50
51 /**
52 * @param array $fields
53 * @param string $enclosure
54 *
55 * @return bool
56 */
57 private static function hasAnyValueWithEscapeFollowedByEnclosure(array $fields, $enclosure)
58 {
59 foreach ($fields as $value) {
60 if (strpos($value, '\\'.$enclosure) !== false) {
61 return true;
62 }
63 }
64
65 return false;
66 }
67
68 /**
69 * @param string | null $eol
70 *
71 * @return bool
72 */
73 private static function resolveEol($eol)
74 {
75 return $eol === null ? self::$defaultEol : (string) $eol;
76 }
77
78 /**
79 * @see http://php.net/manual/en/function.fgetcsv.php
80 *
81 * @param resource $handle
82 * @param int $length
83 * @param string $delimiter
84 * @param string $enclosure
85 * @param string $escape
86 *
87 * @return array|false|null
88 */
89 public static function fGetCsv($handle, $length = 0, $delimiter = ',', $enclosure = '"', $escape = '"')
90 {
91 self::checkGetCsvEscape($enclosure, $escape);
92
93 return \fgetcsv($handle, $length, $delimiter, $enclosure, $enclosure);
94 }
95
96 /**
97 * @see http://php.net/manual/en/function.str_getcsv.php
98 *
99 * @param string $input
100 * @param string $delimiter
101 * @param string $enclosure
102 * @param string $escape
103 *
104 * @return array
105 */
106 public static function strGetCsv($input, $delimiter = ',', $enclosure = '"', $escape = '"')
107 {
108 self::checkGetCsvEscape($enclosure, $escape);
109
110 return \str_getcsv($input, $delimiter, $enclosure, $enclosure);
111 }
112
113 /**
114 * This code was borrowed from goodby/csv under MIT LICENSE.
115 *
116 * @author Hidehito Nozawa <suinyeze@gmail.com>
117 *
118 * @see https://github.com/goodby/csv
119 * @see https://github.com/goodby/csv/blob/c6677d9c68323ef734a67a34f3e5feabcafd5b4e/src/Goodby/CSV/Export/Standard/CsvFileObject.php#L46
120 *
121 * @param array $fields
122 * @param string $delimiter
123 * @param string $enclosure
124 * @param string $eol
125 *
126 * @return string
127 */
128 public static function strPutCsv(array $fields, $delimiter = ',', $enclosure = '"', $eol = self::EOL_WRITE_DEFAULT)
129 {
130 $file = new \SplTempFileObject();
131 $file->fputcsv($fields, $delimiter, $enclosure, '\\');
132 $file->rewind();
133
134 $line = '';
135 while (!$file->eof()) {
136 $line .= $file->fgets();
137 }
138
139 $line = self::fixEnclosureEscape($enclosure, $line);
140
141 if ($eol !== self::EOL_WRITE_DEFAULT) {
142 $line = rtrim($line, "\n").$eol;
143 }
144
145 return $line;
146 }
147
148 /**
149 * Fix the enclosure escape in the given CSV raw line.
150 *
151 * @param string $enclosure
152 * @param string $line
153 */
154 public static function fixEnclosureEscape($enclosure, $line)
155 {
156 return \str_replace('\\'.$enclosure, '\\'.$enclosure.$enclosure, $line);
157 }
158
159 /**
160 * Emits a warning if the escape char is not the default backslash or null.
161 *
162 * @param string $escape
163 */
164 public static function checkPutCsvEscape($escape)
165 {
166 if ($escape !== '\\' && $escape !== null) {
167 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error,WordPress.Security.EscapeOutput.OutputNotEscaped -- runtime warning to PHP error log; not HTML output
168 trigger_error(
169 sprintf(
170 "In writing mode, the escape char must be a backslash '\\'. "
171 ."The given escape char '%s' will be ignored.",
172 esc_html( $escape )
173 ),
174 E_USER_WARNING
175 );
176 }
177 }
178
179 /**
180 * Emits a warning if the enclosure char and escape char are different.
181 *
182 * @param string $enclosure
183 * @param string $escape
184 */
185 public static function checkGetCsvEscape($enclosure, $escape)
186 {
187 if ($enclosure !== $escape) {
188 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error,WordPress.Security.EscapeOutput.OutputNotEscaped -- runtime warning to PHP error log; not HTML output
189 trigger_error(
190 sprintf(
191 'In reading mode, the escape and enclosure chars must be equals. '
192 ."The given escape char '%s' will be ignored.",
193 esc_html( $escape )
194 ),
195 E_USER_WARNING
196 );
197 }
198 }
199
200 /**
201 * @param string $eol
202 */
203 public static function setDefaultWriteEol($eol)
204 {
205 self::$defaultEol = $eol;
206 }
207
208 /**
209 * @return string $eol
210 */
211 public static function getDefaultWriteEol()
212 {
213 return self::$defaultEol;
214 }
215 }
216