PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 3.06.06
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v3.06.06
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/helpers/FrmCSVExportHelper.php +77 -418 6.5.33.06.06 View file →
@@ -1,140 +1,47 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - die( 'You are not allowed to call this page directly.' );
4 -}
5 2
6 3 class FrmCSVExportHelper {
7 4
8 - /**
9 - * @var string $separator
10 - */
11 - protected static $separator = ', ';
12 -
13 - /**
14 - * @var string $column_separator
15 - */
5 + protected static $separator = ', ';
16 6 protected static $column_separator = ',';
17 -
18 - /**
19 - * @var string $line_break
20 - */
21 - protected static $line_break = 'return';
22 -
23 - /**
24 - * @var string $charset
25 - */
26 - protected static $charset = 'UTF-8';
27 -
28 - /**
29 - * @var string $to_encoding
30 - */
31 - protected static $to_encoding = 'UTF-8';
32 -
33 - /**
34 - * @var string $wp_date_format
35 - */
36 - protected static $wp_date_format = 'Y-m-d H:i:s';
37 -
38 - /**
39 - * @var int $comment_count
40 - */
41 - protected static $comment_count = 0;
42 -
43 - /**
44 - * @var int $form_id
45 - */
46 - protected static $form_id = 0;
47 -
48 - /**
49 - * @var array $headings
50 - */
51 - protected static $headings = array();
52 -
53 - /**
54 - * @var array $fields
55 - */
56 - protected static $fields = array();
57 -
58 - /**
59 - * @var stdClass|null $entry
60 - */
7 + protected static $line_break = 'return';
8 + protected static $charset = 'UTF-8';
9 + protected static $to_encoding = 'UTF-8';
10 + protected static $wp_date_format = 'Y-m-d H:i:s';
11 + protected static $comment_count = 0;
12 + protected static $form_id = 0;
13 + protected static $headings = array();
14 + protected static $fields = array();
61 15 protected static $entry;
62 -
63 - /**
64 - * @var bool|null $has_parent_id
65 - */
66 16 protected static $has_parent_id;
67 17
68 - /**
69 - * @var array|null $fields_by_repeater_id
70 - */
71 - protected static $fields_by_repeater_id;
72 -
73 - /**
74 - * @var string $mode either 'echo' or 'file' are supported.
75 - */
76 - protected static $mode = 'echo';
77 -
78 - /**
79 - * @var resource|null $fp used to write a CSV file in file mode.
80 - */
81 - protected static $fp;
82 -
83 - /**
84 - * @var string $context the context of the CSV being generated. Possible values include 'email' when used as an email attachment, or 'default'.
85 - */
86 - protected static $context = 'default';
87 -
88 - /**
89 - * @var array $meta
90 - */
91 - protected static $meta = array();
92 -
93 18 public static function csv_format_options() {
94 19 $formats = array( 'UTF-8', 'ISO-8859-1', 'windows-1256', 'windows-1251', 'macintosh' );
95 20 $formats = apply_filters( 'frm_csv_format_options', $formats );
96 -
97 21 return $formats;
98 22 }
99 23
100 - /**
101 - * @param array $atts
102 - * @return string|false|void returns a string file path or false if $atts['mode'] is set to 'file'.
103 - */
104 24 public static function generate_csv( $atts ) {
105 25 global $frm_vars;
106 26 $frm_vars['prevent_caching'] = true;
107 27
108 - self::$fields = $atts['form_cols'];
28 + self::$fields = $atts['form_cols'];
109 29 self::$form_id = $atts['form']->id;
110 - self::$mode = ! empty( $atts['mode'] ) && 'file' === $atts['mode'] ? 'file' : 'echo';
111 - self::$context = ! empty( $atts['context'] ) ? $atts['context'] : 'default';
112 - self::$meta = ! empty( $atts['meta'] ) ? $atts['meta'] : array();
113 -
114 - self::set_class_parameters();
30 + self::set_class_paramters();
115 31 self::set_has_parent_id( $atts['form'] );
116 32
117 - $filename = self::generate_csv_filename( $atts['form'] );
33 + $filename = apply_filters( 'frm_csv_filename', date( 'ymdHis', time() ) . '_' . sanitize_title_with_dashes( $atts['form']->name ) . '_formidable_entries.csv', $atts['form'] );
118 34 unset( $atts['form'], $atts['form_cols'] );
119 35
120 - if ( 'file' === self::$mode ) {
121 - $filepath = get_temp_dir() . $filename;
122 - self::$fp = @fopen( $filepath, 'w' );
123 - if ( ! self::$fp ) {
124 - return false;
125 - }
126 - } elseif ( 'echo' === self::$mode ) {
127 - self::print_file_headers( $filename );
128 - }
129 -
36 + self::print_file_headers( $filename );
130 37 unset( $filename );
131 38
132 - $comment_count = FrmDb::get_count(
39 + $comment_count = FrmDb::get_count(
133 40 'frm_item_metas',
134 41 array(
135 - 'item_id' => $atts['entry_ids'],
136 - 'field_id' => 0,
42 + 'item_id' => $atts['entry_ids'],
43 + 'field_id' => 0,
137 44 'meta_value like' => '{',
138 45 ),
139 46 array(
140 47 'group_by' => 'item_id',
@@ -149,49 +56,19 @@
149 56 // fetch 20 posts at a time rather than loading the entire table into memory
150 57 while ( $next_set = array_splice( $atts['entry_ids'], 0, 20 ) ) {
151 58 self::prepare_next_csv_rows( $next_set );
152 59 }
153 -
154 - if ( 'file' === self::$mode ) {
155 - fclose( self::$fp );
156 - return $filepath;
157 - }
158 60 }
159 61
160 - /**
161 - * @since 5.0.16
162 - *
163 - * @param stdClass $form
164 - * @return string
165 - */
166 - private static function generate_csv_filename( $form ) {
167 - $filename = gmdate( 'ymdHis', time() ) . '_' . sanitize_title_with_dashes( $form->name ) . '_formidable_entries.csv';
168 - return apply_filters( 'frm_csv_filename', $filename, $form, self::get_standard_filter_args() );
169 - }
170 -
171 - /**
172 - * @since 5.0.16
173 - *
174 - * @return array
175 - */
176 - private static function get_standard_filter_args() {
177 - return array(
178 - 'context' => self::$context,
179 - 'meta' => self::$meta,
180 - );
181 - }
182 -
183 - private static function set_class_parameters() {
184 - $args = self::get_standard_filter_args();
185 - self::$separator = apply_filters( 'frm_csv_sep', self::$separator, $args );
186 - self::$line_break = apply_filters( 'frm_csv_line_break', self::$line_break, $args );
187 - self::$wp_date_format = apply_filters( 'frm_csv_date_format', self::$wp_date_format, $args );
62 + private static function set_class_paramters() {
63 + self::$separator = apply_filters( 'frm_csv_sep', self::$separator );
64 + self::$line_break = apply_filters( 'frm_csv_line_break', self::$line_break );
65 + self::$wp_date_format = apply_filters( 'frm_csv_date_format', self::$wp_date_format );
188 66 self::get_csv_format();
189 67 self::$charset = get_option( 'blog_charset' );
190 68
191 - $col_sep = ! empty( $_POST['csv_col_sep'] ) ? sanitize_text_field( wp_unslash( $_POST['csv_col_sep'] ) ) : self::$column_separator; // phpcs:ignore WordPress.Security.NonceVerification.Missing
192 -
193 - self::$column_separator = apply_filters( 'frm_csv_column_sep', $col_sep, $args );
69 + $col_sep = ( isset( $_POST['csv_col_sep'] ) && ! empty( $_POST['csv_col_sep'] ) ) ? sanitize_text_field( $_POST['csv_col_sep'] ) : self::$column_separator;
70 + self::$column_separator = apply_filters( 'frm_csv_column_sep', $col_sep );
194 71 }
195 72
196 73 private static function set_has_parent_id( $form ) {
197 74 self::$has_parent_id = $form->parent_form_id > 0;
@@ -200,9 +77,9 @@
200 77 private static function print_file_headers( $filename ) {
201 78 header( 'Content-Description: File Transfer' );
202 79 header( 'Content-Disposition: attachment; filename="' . esc_attr( $filename ) . '"' );
203 80 header( 'Content-Type: text/csv; charset=' . self::$charset, true );
204 - header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', mktime( gmdate( 'H' ) + 2, gmdate( 'i' ), gmdate( 's' ), gmdate( 'm' ), gmdate( 'd' ), gmdate( 'Y' ) ) ) . ' GMT' );
81 + header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', mktime( date( 'H' ) + 2, date( 'i' ), date( 's' ), date( 'm' ), date( 'd' ), date( 'Y' ) ) ) . ' GMT' );
205 82 header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
206 83 header( 'Cache-Control: no-cache, must-revalidate' );
207 84 header( 'Pragma: no-cache' );
208 85
@@ -215,10 +92,10 @@
215 92 );
216 93 }
217 94
218 95 public static function get_csv_format() {
219 - $csv_format = FrmAppHelper::get_post_param( 'csv_format', 'UTF-8', 'sanitize_text_field' );
220 - $csv_format = apply_filters( 'frm_csv_format', $csv_format, self::get_standard_filter_args() );
96 + $csv_format = FrmAppHelper::get_post_param( 'csv_format', 'UTF-8', 'sanitize_text_field' );
97 + $csv_format = apply_filters( 'frm_csv_format', $csv_format );
221 98 self::$to_encoding = $csv_format;
222 99 }
223 100
224 101 private static function prepare_csv_headings() {
@@ -223,15 +100,14 @@
223 100
224 101 private static function prepare_csv_headings() {
225 102 $headings = array();
226 103 self::csv_headings( $headings );
227 - $headings = apply_filters(
104 + $headings = apply_filters(
228 105 'frm_csv_columns',
229 106 $headings,
230 107 self::$form_id,
231 - array_merge(
232 - self::get_standard_filter_args(),
233 - array( 'fields' => self::$fields )
108 + array(
109 + 'fields' => self::$fields,
234 110 )
235 111 );
236 112 self::$headings = $headings;
237 113
@@ -237,104 +113,30 @@
237 113
238 114 self::print_csv_row( $headings );
239 115 }
240 116
241 - private static function field_headings( $col ) {
242 - $field_type_obj = FrmFieldFactory::get_field_factory( $col );
243 - if ( ! empty( $field_type_obj->is_combo_field ) ) { // This is combo field.
244 - return $field_type_obj->get_export_headings();
245 - }
246 -
247 - $field_headings = array();
248 - $separate_values = array( 'user_id', 'file', 'data', 'date' );
249 - if ( ! empty( $col->field_options['separate_value'] ) && ! in_array( $col->type, $separate_values, true ) ) {
250 - $field_headings[ $col->id . '_label' ] = strip_tags( $col->name . ' ' . __( '(label)', 'formidable' ) );
251 - }
252 -
253 - $field_headings[ $col->id ] = strip_tags( $col->name );
254 - $field_headings = apply_filters(
255 - 'frm_csv_field_columns',
256 - $field_headings,
257 - array_merge(
258 - self::get_standard_filter_args(),
259 - array( 'field' => $col )
260 - )
261 - );
262 -
263 - return $field_headings;
264 - }
265 -
266 117 private static function csv_headings( &$headings ) {
267 - $fields_by_repeater_id = array();
268 - $repeater_ids = array();
269 -
270 118 foreach ( self::$fields as $col ) {
271 - if ( self::is_the_child_of_a_repeater( $col ) ) {
272 - $repeater_id = $col->field_options['in_section'];
273 - $headings[ 'repeater' . $repeater_id ] = array(); // set a placeholder to maintain order for repeater fields
274 -
275 - if ( ! isset( $fields_by_repeater_id[ $repeater_id ] ) ) {
276 - $fields_by_repeater_id[ $repeater_id ] = array();
277 - $repeater_ids[] = $repeater_id;
278 - }
279 -
280 - $fields_by_repeater_id[ $repeater_id ][] = $col;
281 -
282 - continue;
119 + $field_headings = array();
120 + if ( isset( $col->field_options['separate_value'] ) && $col->field_options['separate_value'] && ! in_array( $col->type, array( 'user_id', 'file', 'data', 'date' ), true ) ) {
121 + $field_headings[ $col->id . '_label' ] = strip_tags( $col->name . ' ' . __( '(label)', 'formidable' ) );
283 122 }
284 123
285 - $headings += self::field_headings( $col );
124 + $field_headings[ $col->id ] = strip_tags( $col->name );
125 + $field_headings = apply_filters(
126 + 'frm_csv_field_columns',
127 + $field_headings,
128 + array(
129 + 'field' => $col,
130 + )
131 + );
132 + $headings += $field_headings;
286 133 }
287 - unset( $repeater_id, $col );
288 134
289 - if ( $repeater_ids ) {
290 - $where = array( 'field_id' => $repeater_ids );
291 - $repeater_meta = FrmDb::get_results( 'frm_item_metas', $where, 'field_id, meta_value' );
292 - $max = array_fill_keys( $repeater_ids, 0 );
293 -
294 - foreach ( $repeater_meta as $row ) {
295 - $start = strpos( $row->meta_value, 'a:' ) + 2;
296 - $end = strpos( $row->meta_value, ':{' );
297 - $length = substr( $row->meta_value, $start, $end - $start );
298 -
299 - if ( $length > $max[ $row->field_id ] ) {
300 - $max[ $row->field_id ] = $length;
301 - }
302 - }
303 - unset( $start, $end, $length, $row, $repeater_meta, $where );
304 -
305 - $flat = array();
306 - foreach ( $headings as $key => $heading ) {
307 - if ( is_array( $heading ) ) {
308 - $repeater_id = str_replace( 'repeater', '', $key );
309 -
310 - $repeater_headings = array();
311 - foreach ( $fields_by_repeater_id[ $repeater_id ] as $col ) {
312 - $repeater_headings += self::field_headings( $col );
313 - }
314 -
315 - for ( $i = 0; $i < $max[ $repeater_id ]; $i ++ ) {
316 - foreach ( $repeater_headings as $repeater_key => $repeater_name ) {
317 - $flat[ $repeater_key . '[' . $i . ']' ] = $repeater_name;
318 - }
319 - }
320 - } else {
321 - $flat[ $key ] = $heading;
322 - }
323 - }
324 -
325 - self::$fields_by_repeater_id = $fields_by_repeater_id;
326 -
327 - unset( $key, $heading, $max, $repeater_headings, $repeater_id, $fields_by_repeater_id );
328 -
329 - $headings = $flat;
330 - unset( $flat );
331 - }
332 -
333 135 if ( self::$comment_count ) {
334 - for ( $i = 0; $i < self::$comment_count; $i ++ ) {
335 - $headings[ 'comment' . $i ] = __( 'Comment', 'formidable' );
336 - $headings[ 'comment_user_id' . $i ] = __( 'Comment User', 'formidable' );
136 + for ( $i = 0; $i < self::$comment_count; $i++ ) {
137 + $headings[ 'comment' . $i ] = __( 'Comment', 'formidable' );
138 + $headings[ 'comment_user_id' . $i ] = __( 'Comment User', 'formidable' );
337 139 $headings[ 'comment_created_at' . $i ] = __( 'Comment Date', 'formidable' );
338 140 }
339 141 unset( $i );
340 142 }
@@ -340,40 +142,19 @@
340 142 }
341 143
342 144 $headings['created_at'] = __( 'Timestamp', 'formidable' );
343 145 $headings['updated_at'] = __( 'Last Updated', 'formidable' );
344 - $headings['user_id'] = __( 'Created By', 'formidable' );
146 + $headings['user_id'] = __( 'Created By', 'formidable' );
345 147 $headings['updated_by'] = __( 'Updated By', 'formidable' );
346 - $headings['is_draft'] = __( 'Entry Status', 'formidable' );
347 - $headings['ip'] = __( 'IP', 'formidable' );
348 - $headings['id'] = __( 'ID', 'formidable' );
349 - $headings['item_key'] = __( 'Key', 'formidable' );
148 + $headings['is_draft'] = __( 'Draft', 'formidable' );
149 + $headings['ip'] = __( 'IP', 'formidable' );
150 + $headings['id'] = __( 'ID', 'formidable' );
151 + $headings['item_key'] = __( 'Key', 'formidable' );
350 152 if ( self::has_parent_id() ) {
351 153 $headings['parent_id'] = __( 'Parent ID', 'formidable' );
352 154 }
353 -
354 - $headings = apply_filters( 'frm_export_csv_headings', $headings );
355 155 }
356 156
357 - /**
358 - * @param object $field
359 - * @return bool
360 - */
361 - private static function is_the_child_of_a_repeater( $field ) {
362 - if ( $field->form_id === self::$form_id || empty( $field->field_options['in_section'] ) ) {
363 - return false;
364 - }
365 -
366 - $section_id = $field->field_options['in_section'];
367 - $section = FrmField::getOne( $section_id );
368 -
369 - if ( ! $section ) {
370 - return false;
371 - }
372 -
373 - return FrmField::is_repeating_field( $section );
374 - }
375 -
376 157 private static function has_parent_id() {
377 158 return self::$has_parent_id;
378 159 }
379 160
@@ -378,11 +159,11 @@
378 159 }
379 160
380 161 private static function prepare_next_csv_rows( $next_set ) {
381 162 // order by parent_item_id so children will be first
382 - $where = array(
383 - 'or' => 1,
384 - 'id' => $next_set,
163 + $where = array(
164 + 'or' => 1,
165 + 'id' => $next_set,
385 166 'parent_item_id' => $next_set,
386 167 );
387 168 $entries = FrmEntry::getAll( $where, ' ORDER BY parent_item_id DESC', '', true, false );
388 169
@@ -408,9 +189,8 @@
408 189 array(
409 190 'entry' => self::$entry,
410 191 'date_format' => self::$wp_date_format,
411 192 'comment_count' => self::$comment_count,
412 - 'context' => self::$context,
413 193 )
414 194 );
415 195 self::print_csv_row( $row );
416 196 }
@@ -424,13 +204,8 @@
424 204 // we need to skip the keys and only process field ids
425 205 continue;
426 206 }
427 207
428 - if ( ! isset( $entries[ self::$entry->parent_item_id ] ) ) {
429 - $entries[ self::$entry->parent_item_id ] = new stdClass();
430 - $entries[ self::$entry->parent_item_id ]->metas = array();
431 - }
432 -
433 208 if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) {
434 209 $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] = array();
435 210 } elseif ( ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) {
436 211 // if the data is here, it should be an array but if this field has collected data
@@ -440,10 +215,8 @@
440 215
441 216 //add the repeated values
442 217 $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ][] = $meta_value;
443 218 }
444 -
445 - self::$entry->metas = self::fill_missing_repeater_metas( self::$entry->metas, $entries );
446 219 $entries[ self::$entry->parent_item_id ]->metas += self::$entry->metas;
447 220 }
448 221
449 222 // add the embedded form id
@@ -452,60 +225,13 @@
452 225 }
453 226 $entries[ self::$entry->parent_item_id ]->embedded_fields[ self::$entry->id ] = self::$entry->form_id;
454 227 }
455 228
456 - /**
457 - * When an empty field is saved, it isn't saved as a meta value
458 - * The export needs all of the meta to be filled in, so we put blank strings for every missing repeater child
459 - *
460 - * @param array $metas
461 - * @param array $entries
462 - * @return array
463 - */
464 - private static function fill_missing_repeater_metas( $metas, &$entries ) {
465 - $field_ids = array_keys( $metas );
466 - $field_id = end( $field_ids );
467 - $field = self::get_field( $field_id );
468 -
469 - if ( ! $field || empty( $field->field_options['in_section'] ) ) {
470 - return $metas;
471 - }
472 -
473 - $repeater_id = $field->field_options['in_section'];
474 - if ( ! isset( self::$fields_by_repeater_id[ $repeater_id ] ) ) {
475 - return $metas;
476 - }
477 -
478 - foreach ( self::$fields_by_repeater_id[ $repeater_id ] as $repeater_child ) {
479 - if ( ! isset( $metas[ $repeater_child->id ] ) ) {
480 - $metas[ $repeater_child->id ] = '';
481 -
482 - if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) || ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) ) {
483 - $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] = array();
484 - }
485 -
486 - $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ][] = '';
487 - }
488 - }
489 -
490 - return $metas;
491 - }
492 -
493 - private static function get_field( $field_id ) {
494 - $field_id = (int) $field_id;
495 - foreach ( self::$fields as $field ) {
496 - if ( $field_id === (int) $field->id ) {
497 - return $field;
498 - }
499 - }
500 - return false;
501 - }
502 -
503 229 private static function add_field_values_to_csv( &$row ) {
504 230 foreach ( self::$fields as $col ) {
505 231 $field_value = isset( self::$entry->metas[ $col->id ] ) ? self::$entry->metas[ $col->id ] : false;
506 232
507 - FrmFieldsHelper::prepare_field_value( $field_value, $col->type );
233 + $field_value = maybe_unserialize( $field_value );
508 234 self::add_array_values_to_columns( $row, compact( 'col', 'field_value' ) );
509 235
510 236 $field_value = apply_filters(
511 237 'frm_csv_value',
@@ -513,26 +239,26 @@
513 239 array(
514 240 'field' => $col,
515 241 'entry' => self::$entry,
516 242 'separator' => self::$separator,
517 - 'context' => self::$context,
518 243 )
519 244 );
520 245
521 - if ( ! empty( $col->field_options['separate_value'] ) ) {
522 - $label_key = $col->id . '_label';
523 - if ( self::is_the_child_of_a_repeater( $col ) ) {
524 - $row[ $label_key ] = array();
525 -
526 - if ( is_array( $field_value ) ) {
527 - foreach ( $field_value as $value ) {
528 - $row[ $label_key ][] = self::get_separate_value_label( $value, $col );
529 - }
530 - }
531 - } else {
532 - $row[ $label_key ] = self::get_separate_value_label( $field_value, $col );
533 - }
534 - unset( $label_key );
246 + if ( isset( $col->field_options['separate_value'] ) && $col->field_options['separate_value'] ) {
247 + $sep_value = FrmEntriesHelper::display_value(
248 + $field_value,
249 + $col,
250 + array(
251 + 'type' => $col->type,
252 + 'post_id' => self::$entry->post_id,
253 + 'show_icon' => false,
254 + 'entry_id' => self::$entry->id,
255 + 'sep' => self::$separator,
256 + 'embedded_field_id' => ( isset( self::$entry->embedded_fields ) && isset( self::$entry->embedded_fields[ self::$entry->id ] ) ) ? 'form' . self::$entry->embedded_fields[ self::$entry->id ] : 0,
257 + )
258 + );
259 + $row[ $col->id . '_label' ] = $sep_value;
260 + unset( $sep_value );
535 261 }
536 262
537 263 $row[ $col->id ] = $field_value;
538 264
@@ -540,47 +266,13 @@
540 266 }
541 267 }
542 268
543 269 /**
544 - * @since 5.0.06
545 - *
546 - * @param mixed $field_value
547 - * @param stdClass $field
548 - * @return string
549 - */
550 - private static function get_separate_value_label( $field_value, $field ) {
551 - return FrmEntriesHelper::display_value(
552 - $field_value,
553 - $field,
554 - array(
555 - 'type' => $field->type,
556 - 'post_id' => self::$entry->post_id,
557 - 'show_icon' => false,
558 - 'entry_id' => self::$entry->id,
559 - 'sep' => self::$separator,
560 - 'embedded_field_id' => ( isset( self::$entry->embedded_fields ) && isset( self::$entry->embedded_fields[ self::$entry->id ] ) ) ? 'form' . self::$entry->embedded_fields[ self::$entry->id ] : 0,
561 - )
562 - );
563 - }
564 -
565 - /**
566 270 * @since 2.0.23
567 271 */
568 272 private static function add_array_values_to_columns( &$row, $atts ) {
569 273 if ( is_array( $atts['field_value'] ) ) {
570 274 foreach ( $atts['field_value'] as $key => $sub_value ) {
571 - if ( is_array( $sub_value ) ) {
572 - // This is combo field inside repeater. The heading key has this format: [86_first[0]].
573 - foreach ( $sub_value as $sub_key => $sub_sub_value ) {
574 - $column_key = $atts['col']->id . '_' . $sub_key . '[' . $key . ']';
575 - if ( ! is_numeric( $sub_key ) && isset( self::$headings[ $column_key ] ) ) {
576 - $row[ $column_key ] = $sub_sub_value;
577 - }
578 - }
579 -
580 - continue;
581 - }
582 -
583 275 $column_key = $atts['col']->id . '_' . $key;
584 276 if ( ! is_numeric( $key ) && isset( self::$headings[ $column_key ] ) ) {
585 277 $row[ $column_key ] = $sub_value;
586 278 }
@@ -590,14 +282,14 @@
590 282
591 283 private static function add_entry_data_to_csv( &$row ) {
592 284 $row['created_at'] = FrmAppHelper::get_formatted_time( self::$entry->created_at, self::$wp_date_format, ' ' );
593 285 $row['updated_at'] = FrmAppHelper::get_formatted_time( self::$entry->updated_at, self::$wp_date_format, ' ' );
594 - $row['user_id'] = self::$entry->user_id;
286 + $row['user_id'] = self::$entry->user_id;
595 287 $row['updated_by'] = self::$entry->updated_by;
596 - $row['is_draft'] = self::$entry->is_draft;
597 - $row['ip'] = self::$entry->ip;
598 - $row['id'] = self::$entry->id;
599 - $row['item_key'] = self::$entry->item_key;
288 + $row['is_draft'] = self::$entry->is_draft ? '1' : '0';
289 + $row['ip'] = self::$entry->ip;
290 + $row['id'] = self::$entry->id;
291 + $row['item_key'] = self::$entry->item_key;
600 292 if ( self::has_parent_id() ) {
601 293 $row['parent_id'] = self::$entry->parent_item_id;
602 294 }
603 295 }
@@ -602,30 +294,12 @@
602 294 }
603 295 }
604 296
605 297 private static function print_csv_row( $rows ) {
606 - $sep = '';
607 - $echo = 'echo' === self::$mode;
298 + $sep = '';
608 299
609 300 foreach ( self::$headings as $k => $heading ) {
610 - if ( isset( $rows[ $k ] ) ) {
611 - $row = $rows[ $k ];
612 - } else {
613 - $row = '';
614 - // array indexed data is not at $rows[ $k ]
615 - if ( $k[ strlen( $k ) - 1 ] === ']' ) {
616 - $start = strrpos( $k, '[' );
617 - $key = substr( $k, 0, $start ++ );
618 - $index = substr( $k, $start, strlen( $k ) - 1 - $start );
619 -
620 - if ( isset( $rows[ $key ] ) && isset( $rows[ $key ][ $index ] ) ) {
621 - $row = $rows[ $key ][ $index ];
622 - }
623 -
624 - unset( $start, $key, $index );
625 - }
626 - }
627 -
301 + $row = isset( $rows[ $k ] ) ? $rows[ $k ] : '';
628 302 if ( is_array( $row ) ) {
629 303 // implode the repeated field values
630 304 $row = implode( self::$separator, FrmAppHelper::array_flatten( $row, 'reset' ) );
631 305 }
@@ -634,22 +308,14 @@
634 308 if ( 'return' !== self::$line_break ) {
635 309 $val = str_replace( array( "\r\n", "\r", "\n" ), self::$line_break, $val );
636 310 }
637 311
638 - if ( $echo ) {
639 - echo $sep . '"' . $val . '"'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
640 - } else {
641 - fwrite( self::$fp, $sep . '"' . $val . '"' );
642 - }
312 + echo $sep . '"' . $val . '"'; // WPCS: XSS ok.
643 313 $sep = self::$column_separator;
644 314
645 315 unset( $k, $row );
646 316 }
647 - if ( $echo ) {
648 - echo "\n";
649 - } else {
650 - fwrite( self::$fp, "\n" );
651 - }
317 + echo "\n";
652 318 }
653 319
654 320 public static function encode_value( $line ) {
655 321 if ( '' === $line ) {
@@ -677,27 +343,20 @@
677 343 $line = iconv( self::$charset, self::$to_encoding . '//IGNORE', $line );
678 344 }
679 345
680 346 return self::escape_csv( $line );
681 - }
347 + }
682 348
683 349 /**
684 350 * Escape a " in a csv with another "
685 351 *
686 352 * @since 2.0
687 - * @param mixed $value
688 - * @return mixed
689 353 */
690 354 public static function escape_csv( $value ) {
691 - if ( ! is_string( $value ) ) {
692 - return $value;
693 - }
694 -
695 355 if ( '=' === $value[0] ) {
696 356 // escape the = to prevent vulnerability
697 357 $value = "'" . $value;
698 358 }
699 359 $value = str_replace( '"', '""', $value );
700 -
701 360 return $value;
702 361 }
703 362 }