PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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 +168 -69 6.25 → trunk View file →
@@ -113,19 +113,19 @@
113 113 // Do not add the UTF-8 with BOM option if this function is called on Global Settings.
114 114 // This is to improve compatibility with the Export View as CSV add-on (v1.10).
115 115 // Otherwise, the option will appear twice since it is added in the add-on as well.
116 116 $on_global_settings_page = 'formidable-settings' === FrmAppHelper::get_param( 'page' );
117 +
117 118 if ( ! $on_global_settings_page ) {
118 119 array_splice( $formats, 1, 0, 'UTF-8 with BOM' );
119 120 }
120 121
121 - $formats = apply_filters( 'frm_csv_format_options', $formats );
122 -
123 - return $formats;
122 + return apply_filters( 'frm_csv_format_options', $formats );
124 123 }
125 124
126 125 /**
127 126 * @param array $atts
127 + *
128 128 * @return false|string|null returns a string file path or false if $atts['mode'] is set to 'file'.
129 129 */
130 130 public static function generate_csv( $atts ) {
131 131 global $frm_vars;
@@ -144,8 +144,9 @@
144 144
145 145 if ( 'file' === self::$mode ) {
146 146 $filepath = get_temp_dir() . $filename;
147 147 self::$fp = @fopen( $filepath, 'w' );
148 +
148 149 if ( ! self::$fp ) {
149 150 return false;
150 151 }
151 152 } elseif ( 'echo' === self::$mode ) {
@@ -153,9 +154,9 @@
153 154 }
154 155
155 156 unset( $filename );
156 157
157 - $comment_count = FrmDb::get_count(
158 + self::$comment_count = FrmDb::get_count(
158 159 'frm_item_metas',
159 160 array(
160 161 'item_id' => $atts['entry_ids'],
161 162 'field_id' => 0,
@@ -166,9 +167,8 @@
166 167 'order_by' => 'count(*) DESC',
167 168 'limit' => 1,
168 169 )
169 170 );
170 - self::$comment_count = $comment_count;
171 171
172 172 self::prepare_csv_headings();
173 173
174 174 /**
@@ -202,8 +202,9 @@
202 202 /**
203 203 * @since 6.8.4
204 204 *
205 205 * @param array $atts
206 + *
206 207 * @return void
207 208 */
208 209 private static function after_generate_csv( $atts ) {
209 210 /**
@@ -209,8 +210,9 @@
209 210 /**
210 211 * @since 6.8.4
211 212 *
212 213 * @param array $atts {
214 + *
213 215 * @type object $form
214 216 * @type array $entry_ids
215 217 * @type array $form_cols
216 218 * }
@@ -221,8 +223,9 @@
221 223 /**
222 224 * @since 5.0.16
223 225 *
224 226 * @param stdClass $form
227 + *
225 228 * @return string
226 229 */
227 230 private static function generate_csv_filename( $form ) {
228 231 $filename = gmdate( 'ymdHis', time() ) . '_' . sanitize_title_with_dashes( $form->name ) . '_formidable_entries.csv';
@@ -240,8 +243,11 @@
240 243 'meta' => self::$meta,
241 244 );
242 245 }
243 246
247 + /**
248 + * @return void
249 + */
244 250 private static function set_class_parameters() {
245 251 $args = self::get_standard_filter_args();
246 252 self::$separator = apply_filters( 'frm_csv_sep', self::$separator, $args );
247 253 self::$line_break = apply_filters( 'frm_csv_line_break', self::$line_break, $args );
@@ -248,17 +254,28 @@
248 254 self::$wp_date_format = apply_filters( 'frm_csv_date_format', self::$wp_date_format, $args );
249 255 self::get_csv_format();
250 256 self::$charset = get_option( 'blog_charset' );
251 257
252 - $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
258 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
259 + $col_sep = ! empty( $_POST['csv_col_sep'] ) ? sanitize_text_field( wp_unslash( $_POST['csv_col_sep'] ) ) : self::$column_separator;
253 260
254 261 self::$column_separator = apply_filters( 'frm_csv_column_sep', $col_sep, $args );
255 262 }
256 263
264 + /**
265 + * @param object $form
266 + *
267 + * @return void
268 + */
257 269 private static function set_has_parent_id( $form ) {
258 270 self::$has_parent_id = $form->parent_form_id > 0;
259 271 }
260 272
273 + /**
274 + * @param string $filename
275 + *
276 + * @return void
277 + */
261 278 private static function print_file_headers( $filename ) {
262 279 header( 'Content-Description: File Transfer' );
263 280 header( 'Content-Disposition: attachment; filename="' . esc_attr( $filename ) . '"' );
264 281 header( 'Content-Type: text/csv; charset=' . self::$charset, true );
@@ -296,8 +313,11 @@
296 313 $csv_format = apply_filters( 'frm_csv_format', $csv_format, self::get_standard_filter_args() );
297 314 self::$to_encoding = $csv_format;
298 315 }
299 316
317 + /**
318 + * @return void
319 + */
300 320 private static function prepare_csv_headings() {
301 321 $headings = array();
302 322 self::csv_headings( $headings );
303 323 $headings = apply_filters(
@@ -313,10 +333,16 @@
313 333
314 334 self::print_csv_row( $headings );
315 335 }
316 336
337 + /**
338 + * @param object $col
339 + *
340 + * @return array
341 + */
317 342 private static function field_headings( $col ) {
318 343 $field_type_obj = FrmFieldFactory::get_field_factory( $col );
344 +
319 345 if ( ! empty( $field_type_obj->is_combo_field ) ) {
320 346 // This is combo field.
321 347 return $field_type_obj->get_export_headings();
322 348 }
@@ -322,14 +348,20 @@
322 348 }
323 349
324 350 $field_headings = array();
325 351 $separate_values = array( 'user_id', 'file', 'data', 'date' );
352 +
326 353 if ( ! empty( $col->field_options['separate_value'] ) && ! in_array( $col->type, $separate_values, true ) ) {
327 354 $field_headings[ $col->id . '_label' ] = strip_tags( $col->name . ' ' . __( '(label)', 'formidable' ) );
328 355 }
329 356
330 - $field_headings[ $col->id ] = strip_tags( $col->name );
331 - $field_headings = apply_filters(
357 + if ( ! empty( $field_headings[ $col->id . '_label' ] ) ) {
358 + $field_headings[ $col->id ] = strip_tags( $col->name . ' ' . __( '(value)', 'formidable' ) );
359 + } else {
360 + $field_headings[ $col->id ] = strip_tags( $col->name );
361 + }
362 +
363 + return apply_filters(
332 364 'frm_csv_field_columns',
333 365 $field_headings,
334 366 array_merge(
335 367 self::get_standard_filter_args(),
@@ -335,13 +367,16 @@
335 367 self::get_standard_filter_args(),
336 368 array( 'field' => $col )
337 369 )
338 370 );
339 -
340 - return $field_headings;
341 371 }
342 372
343 - private static function csv_headings( &$headings ) {
373 + /**
374 + * @param array $headings
375 + *
376 + * @return void
377 + */
378 + private static function csv_headings( &$headings ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
344 379 $fields_by_repeater_id = array();
345 380 $repeater_ids = array();
346 381
347 382 foreach ( self::$fields as $col ) {
@@ -380,24 +415,26 @@
380 415 }
381 416 unset( $start, $end, $length, $row, $repeater_meta, $where );
382 417
383 418 $flat = array();
419 +
384 420 foreach ( $headings as $key => $heading ) {
385 - if ( is_array( $heading ) ) {
386 - $repeater_id = str_replace( 'repeater', '', $key );
421 + if ( ! is_array( $heading ) ) {
422 + $flat[ $key ] = $heading;
423 + continue;
424 + }
387 425
388 - $repeater_headings = array();
389 - foreach ( $fields_by_repeater_id[ $repeater_id ] as $col ) {
390 - $repeater_headings += self::field_headings( $col );
391 - }
426 + $repeater_id = str_replace( 'repeater', '', $key );
427 + $repeater_headings = array();
392 428
393 - for ( $i = 0; $i < $max[ $repeater_id ]; $i++ ) {
394 - foreach ( $repeater_headings as $repeater_key => $repeater_name ) {
395 - $flat[ $repeater_key . '[' . $i . ']' ] = $repeater_name;
396 - }
429 + foreach ( $fields_by_repeater_id[ $repeater_id ] as $col ) {
430 + $repeater_headings += self::field_headings( $col );
431 + }
432 +
433 + for ( $i = 0; $i < $max[ $repeater_id ]; $i++ ) {
434 + foreach ( $repeater_headings as $repeater_key => $repeater_name ) {
435 + $flat[ $repeater_key . '[' . $i . ']' ] = $repeater_name;
397 436 }
398 - } else {
399 - $flat[ $key ] = $heading;
400 437 }
401 438 }
402 439
403 440 self::$fields_by_repeater_id = $fields_by_repeater_id;
@@ -424,8 +461,9 @@
424 461 $headings['is_draft'] = __( 'Entry Status', 'formidable' );
425 462 $headings['ip'] = __( 'IP', 'formidable' );
426 463 $headings['id'] = __( 'ID', 'formidable' );
427 464 $headings['item_key'] = __( 'Key', 'formidable' );
465 +
428 466 if ( self::has_parent_id() ) {
429 467 $headings['parent_id'] = __( 'Parent ID', 'formidable' );
430 468 }
431 469
@@ -433,8 +471,9 @@
433 471 }
434 472
435 473 /**
436 474 * @param object $field
475 + *
437 476 * @return bool
438 477 */
439 478 private static function is_the_child_of_a_repeater( $field ) {
440 479 if ( $field->form_id === self::$form_id || empty( $field->field_options['in_section'] ) ) {
@@ -443,22 +482,26 @@
443 482
444 483 $section_id = $field->field_options['in_section'];
445 484 $section = FrmField::getOne( $section_id );
446 485
447 - if ( ! $section ) {
448 - return false;
449 - }
450 -
451 - return FrmField::is_repeating_field( $section );
486 + return $section && FrmField::is_repeating_field( $section );
452 487 }
453 488
489 + /**
490 + * @return bool
491 + */
454 492 private static function has_parent_id() {
455 493 return self::$has_parent_id;
456 494 }
457 495
496 + /**
497 + * @param array $next_set
498 + *
499 + * @return void
500 + */
458 501 private static function prepare_next_csv_rows( $next_set ) {
459 502 if ( FrmAppHelper::pro_is_installed() ) {
460 - $where = array(
503 + $where = array(
461 504 'or' => 1,
462 505 'id' => $next_set,
463 506 'parent_item_id' => $next_set,
464 507 );
@@ -465,9 +508,9 @@
465 508 // Order by parent_item_id so children will be first.
466 509 $order_by = ' ORDER BY parent_item_id DESC';
467 510 } else {
468 511 // When Pro is not installed, only query for direct ID matches only as we do not expect parent item id
469 - // matches and the more simplified query is faster.
512 + // Matches and the more simplified query is faster.
470 513 $where = array(
471 514 'id' => $next_set,
472 515 );
473 516 $order_by = '';
@@ -478,16 +521,19 @@
478 521 foreach ( $entries as $entry ) {
479 522 self::$entry = $entry;
480 523 unset( $entry );
481 524
482 - if ( self::$entry->form_id !== self::$form_id ) {
525 + if ( self::$entry->form_id === self::$form_id ) {
526 + self::prepare_csv_row();
527 + } else {
483 528 self::add_repeat_field_values_to_csv( $entries );
484 - } else {
485 - self::prepare_csv_row();
486 529 }
487 530 }
488 531 }
489 532
533 + /**
534 + * @return void
535 + */
490 536 private static function prepare_csv_row() {
491 537 $row = array();
492 538 self::add_field_values_to_csv( $row );
493 539 self::add_entry_data_to_csv( $row );
@@ -503,15 +549,20 @@
503 549 );
504 550 self::print_csv_row( $row );
505 551 }
506 552
553 + /**
554 + * @param array $entries
555 + *
556 + * @return void
557 + */
507 558 private static function add_repeat_field_values_to_csv( &$entries ) {
508 559 if ( isset( self::$entry->metas ) ) {
509 - // add child entries to the parent
560 + // Add child entries to the parent
510 561 foreach ( self::$entry->metas as $meta_id => $meta_value ) {
511 562 if ( ! is_numeric( $meta_id ) || '' === $meta_value ) {
512 - // if the hook is being used to include field keys in the metas array,
513 - // we need to skip the keys and only process field ids
563 + // If the hook is being used to include field keys in the metas array,
564 + // We need to skip the keys and only process field ids
514 565 continue;
515 566 }
516 567
517 568 if ( ! isset( $entries[ self::$entry->parent_item_id ] ) ) {
@@ -521,10 +572,10 @@
521 572
522 573 if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) {
523 574 $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] = array();
524 575 } elseif ( ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) {
525 - // if the data is here, it should be an array but if this field has collected data
526 - // both while inside and outside of the repeating section, it's possible this is a string.
576 + // If the data is here, it should be an array but if this field has collected data
577 + // Both while inside and outside of the repeating section, it's possible this is a string.
527 578 $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] = (array) $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ];
528 579 }
529 580
530 581 // Add the repeated values.
@@ -534,12 +585,13 @@
534 585 self::$entry->metas = self::fill_missing_repeater_metas( self::$entry->metas, $entries );
535 586 $entries[ self::$entry->parent_item_id ]->metas += self::$entry->metas;
536 587 }//end if
537 588
538 - // add the embedded form id
589 + // Add the embedded form id
539 590 if ( ! isset( $entries[ self::$entry->parent_item_id ]->embedded_fields ) ) {
540 591 $entries[ self::$entry->parent_item_id ]->embedded_fields = array();
541 592 }
593 +
542 594 $entries[ self::$entry->parent_item_id ]->embedded_fields[ self::$entry->id ] = self::$entry->form_id;
543 595 }
544 596
545 597 /**
@@ -547,14 +599,14 @@
547 599 * The export needs all of the meta to be filled in, so we put blank strings for every missing repeater child
548 600 *
549 601 * @param array $metas
550 602 * @param array $entries
603 + *
551 604 * @return array
552 605 */
553 606 private static function fill_missing_repeater_metas( $metas, &$entries ) {
554 - $field_ids = array_keys( $metas );
555 - $field_id = end( $field_ids );
556 - $field = self::get_field( $field_id );
607 + $field_id = array_key_last( $metas );
608 + $field = self::get_field( $field_id );
557 609
558 610 if ( ! $field || empty( $field->field_options['in_section'] ) ) {
559 611 return $metas;
560 612 }
@@ -559,37 +611,52 @@
559 611 return $metas;
560 612 }
561 613
562 614 $repeater_id = $field->field_options['in_section'];
615 +
563 616 if ( ! isset( self::$fields_by_repeater_id[ $repeater_id ] ) ) {
564 617 return $metas;
565 618 }
566 619
567 620 foreach ( self::$fields_by_repeater_id[ $repeater_id ] as $repeater_child ) {
568 - if ( ! isset( $metas[ $repeater_child->id ] ) ) {
569 - $metas[ $repeater_child->id ] = '';
621 + if ( isset( $metas[ $repeater_child->id ] ) ) {
622 + continue;
623 + }
570 624
571 - if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) || ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) ) {
572 - $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] = array();
573 - }
625 + $metas[ $repeater_child->id ] = '';
574 626
575 - $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ][] = '';
627 + if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) || ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) ) { // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
628 + $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] = array();
576 629 }
630 +
631 + $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ][] = '';
577 632 }
578 633
579 634 return $metas;
580 635 }
581 636
637 + /**
638 + * @param int|string $field_id
639 + *
640 + * @return false|object
641 + */
582 642 private static function get_field( $field_id ) {
583 643 $field_id = (int) $field_id;
644 +
584 645 foreach ( self::$fields as $field ) {
585 646 if ( $field_id === (int) $field->id ) {
586 647 return $field;
587 648 }
588 649 }
650 +
589 651 return false;
590 652 }
591 653
654 + /**
655 + * @param array $row
656 + *
657 + * @return void
658 + */
592 659 private static function add_field_values_to_csv( &$row ) {
593 660 foreach ( self::$fields as $col ) {
594 661 $field_value = self::$entry->metas[ $col->id ] ?? false;
595 662
@@ -608,8 +675,9 @@
608 675 );
609 676
610 677 if ( ! empty( $col->field_options['separate_value'] ) ) {
611 678 $label_key = $col->id . '_label';
679 +
612 680 if ( self::is_the_child_of_a_repeater( $col ) ) {
613 681 $row[ $label_key ] = array();
614 682
615 683 if ( is_array( $field_value ) ) {
@@ -633,8 +701,9 @@
633 701 * @since 5.0.06
634 702 *
635 703 * @param mixed $field_value
636 704 * @param stdClass $field
705 + *
637 706 * @return string
638 707 */
639 708 private static function get_separate_value_label( $field_value, $field ) {
640 709 return FrmEntriesHelper::display_value(
@@ -645,9 +714,9 @@
645 714 'post_id' => self::$entry->post_id,
646 715 'show_icon' => false,
647 716 'entry_id' => self::$entry->id,
648 717 'sep' => self::$separator,
649 - '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,
718 + '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, // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
650 719 )
651 720 );
652 721 }
653 722
@@ -652,32 +721,46 @@
652 721 }
653 722
654 723 /**
655 724 * @since 2.0.23
725 + *
726 + * @param array $row
727 + * @param array $atts
728 + *
729 + * @return void
656 730 */
657 731 private static function add_array_values_to_columns( &$row, $atts ) {
658 - if ( is_array( $atts['field_value'] ) ) {
659 - foreach ( $atts['field_value'] as $key => $sub_value ) {
660 - if ( is_array( $sub_value ) ) {
661 - // This is combo field inside repeater. The heading key has this format: [86_first[0]].
662 - foreach ( $sub_value as $sub_key => $sub_sub_value ) {
663 - $column_key = $atts['col']->id . '_' . $sub_key . '[' . $key . ']';
664 - if ( ! is_numeric( $sub_key ) && isset( self::$headings[ $column_key ] ) ) {
665 - $row[ $column_key ] = $sub_sub_value;
666 - }
732 + if ( ! is_array( $atts['field_value'] ) ) {
733 + return;
734 + }
735 +
736 + foreach ( $atts['field_value'] as $key => $sub_value ) {
737 + if ( is_array( $sub_value ) ) {
738 + // This is combo field inside repeater. The heading key has this format: [86_first[0]].
739 + foreach ( $sub_value as $sub_key => $sub_sub_value ) {
740 + $column_key = $atts['col']->id . '_' . $sub_key . '[' . $key . ']';
741 +
742 + if ( ! is_numeric( $sub_key ) && isset( self::$headings[ $column_key ] ) ) {
743 + $row[ $column_key ] = $sub_sub_value;
667 744 }
745 + }
668 746
669 - continue;
670 - }
747 + continue;
748 + }
671 749
672 - $column_key = $atts['col']->id . '_' . $key;
673 - if ( ! is_numeric( $key ) && isset( self::$headings[ $column_key ] ) ) {
674 - $row[ $column_key ] = $sub_value;
675 - }
750 + $column_key = $atts['col']->id . '_' . $key;
751 +
752 + if ( ! is_numeric( $key ) && isset( self::$headings[ $column_key ] ) ) {
753 + $row[ $column_key ] = $sub_value;
676 754 }
677 755 }
678 756 }
679 757
758 + /**
759 + * @param array $row
760 + *
761 + * @return void
762 + */
680 763 private static function add_entry_data_to_csv( &$row ) {
681 764 $row['created_at'] = FrmAppHelper::get_formatted_time( self::$entry->created_at, self::$wp_date_format, ' ' );
682 765 $row['updated_at'] = FrmAppHelper::get_formatted_time( self::$entry->updated_at, self::$wp_date_format, ' ' );
683 766 $row['user_id'] = self::$entry->user_id;
@@ -685,13 +768,19 @@
685 768 $row['is_draft'] = self::$entry->is_draft;
686 769 $row['ip'] = self::$entry->ip;
687 770 $row['id'] = self::$entry->id;
688 771 $row['item_key'] = self::$entry->item_key;
772 +
689 773 if ( self::has_parent_id() ) {
690 774 $row['parent_id'] = self::$entry->parent_item_id;
691 775 }
692 776 }
693 777
778 + /**
779 + * @param array $rows
780 + *
781 + * @return void
782 + */
694 783 private static function print_csv_row( $rows ) {
695 784 $sep = '';
696 785 $echo = 'echo' === self::$mode;
697 786
@@ -699,8 +788,9 @@
699 788 if ( isset( $rows[ $k ] ) ) {
700 789 $row = $rows[ $k ];
701 790 } else {
702 791 $row = '';
792 +
703 793 // array indexed data is not at $rows[ $k ]
704 794 if ( $k[ strlen( $k ) - 1 ] === ']' ) {
705 795 $start = strrpos( $k, '[' );
706 796 $key = substr( $k, 0, $start++ );
@@ -714,13 +804,14 @@
714 804 }
715 805 }
716 806
717 807 if ( is_array( $row ) ) {
718 - // implode the repeated field values
808 + // Implode the repeated field values
719 809 $row = implode( self::$separator, FrmAppHelper::array_flatten( $row, 'reset' ) );
720 810 }
721 811
722 812 $val = self::encode_value( $row );
813 +
723 814 if ( 'return' !== self::$line_break ) {
724 815 $val = str_replace( array( "\r\n", "\r", "\n" ), self::$line_break, $val );
725 816 }
726 817
@@ -728,12 +819,14 @@
728 819 echo $sep . '"' . $val . '"'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
729 820 } else {
730 821 fwrite( self::$fp, $sep . '"' . $val . '"' );
731 822 }
823 +
732 824 $sep = self::$column_separator;
733 825
734 826 unset( $k, $row );
735 827 }//end foreach
828 +
736 829 if ( $echo ) {
737 830 echo "\n";
738 831 } else {
739 832 fwrite( self::$fp, "\n" );
@@ -739,8 +832,13 @@
739 832 fwrite( self::$fp, "\n" );
740 833 }
741 834 }
742 835
836 + /**
837 + * @param string $line
838 + *
839 + * @return string
840 + */
743 841 public static function encode_value( $line ) {
744 842 if ( '' === $line ) {
745 843 return $line;
746 844 }
@@ -748,12 +846,12 @@
748 846 $convmap = false;
749 847
750 848 switch ( self::$to_encoding ) {
751 849 case 'macintosh':
752 - // this map was derived from the differences between the MacRoman and UTF-8 Charsets
850 + // This map was derived from the differences between the MacRoman and UTF-8 Charsets
753 851 // Reference:
754 852 // http://www.alanwood.net/demos/macroman.html.
755 - $convmap = array( 256, 304, 0, 0xffff, 306, 337, 0, 0xffff, 340, 375, 0, 0xffff, 377, 401, 0, 0xffff, 403, 709, 0, 0xffff, 712, 727, 0, 0xffff, 734, 936, 0, 0xffff, 938, 959, 0, 0xffff, 961, 8210, 0, 0xffff, 8213, 8215, 0, 0xffff, 8219, 8219, 0, 0xffff, 8227, 8229, 0, 0xffff, 8231, 8239, 0, 0xffff, 8241, 8248, 0, 0xffff, 8251, 8259, 0, 0xffff, 8261, 8363, 0, 0xffff, 8365, 8481, 0, 0xffff, 8483, 8705, 0, 0xffff, 8707, 8709, 0, 0xffff, 8711, 8718, 0, 0xffff, 8720, 8720, 0, 0xffff, 8722, 8729, 0, 0xffff, 8731, 8733, 0, 0xffff, 8735, 8746, 0, 0xffff, 8748, 8775, 0, 0xffff, 8777, 8799, 0, 0xffff, 8801, 8803, 0, 0xffff, 8806, 9673, 0, 0xffff, 9675, 63742, 0, 0xffff, 63744, 64256, 0, 0xffff );
853 + $convmap = array( 256, 304, 0, 0xffff, 306, 337, 0, 0xffff, 340, 375, 0, 0xffff, 377, 401, 0, 0xffff, 403, 709, 0, 0xffff, 712, 727, 0, 0xffff, 734, 936, 0, 0xffff, 938, 959, 0, 0xffff, 961, 8210, 0, 0xffff, 8213, 8215, 0, 0xffff, 8219, 8219, 0, 0xffff, 8227, 8229, 0, 0xffff, 8231, 8239, 0, 0xffff, 8241, 8248, 0, 0xffff, 8251, 8259, 0, 0xffff, 8261, 8363, 0, 0xffff, 8365, 8481, 0, 0xffff, 8483, 8705, 0, 0xffff, 8707, 8709, 0, 0xffff, 8711, 8718, 0, 0xffff, 8720, 8720, 0, 0xffff, 8722, 8729, 0, 0xffff, 8731, 8733, 0, 0xffff, 8735, 8746, 0, 0xffff, 8748, 8775, 0, 0xffff, 8777, 8799, 0, 0xffff, 8801, 8803, 0, 0xffff, 8806, 9673, 0, 0xffff, 9675, 63742, 0, 0xffff, 63744, 64256, 0, 0xffff ); // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
756 854 break;
757 855 case 'ISO-8859-1':
758 856 $convmap = array( 256, 10000, 0, 0xffff );
759 857 }
@@ -772,9 +870,11 @@
772 870 /**
773 871 * Escape a " in a csv with another "
774 872 *
775 873 * @since 2.0
874 + *
776 875 * @param mixed $value
876 + *
777 877 * @return mixed
778 878 */
779 879 public static function escape_csv( $value ) {
780 880 if ( ! is_string( $value ) ) {
@@ -784,9 +884,8 @@
784 884 if ( '=' === $value[0] ) {
785 885 // escape the = to prevent vulnerability
786 886 $value = "'" . $value;
787 887 }
788 - $value = str_replace( '"', '""', $value );
789 888
790 - return $value;
889 + return str_replace( '"', '""', $value );
791 890 }
792 891 }