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 +163 -68 6.25.1 → 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,8 +348,9 @@
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
@@ -331,9 +358,10 @@
331 358 $field_headings[ $col->id ] = strip_tags( $col->name . ' ' . __( '(value)', 'formidable' ) );
332 359 } else {
333 360 $field_headings[ $col->id ] = strip_tags( $col->name );
334 361 }
335 - $field_headings = apply_filters(
362 +
363 + return apply_filters(
336 364 'frm_csv_field_columns',
337 365 $field_headings,
338 366 array_merge(
339 367 self::get_standard_filter_args(),
@@ -339,13 +367,16 @@
339 367 self::get_standard_filter_args(),
340 368 array( 'field' => $col )
341 369 )
342 370 );
343 -
344 - return $field_headings;
345 371 }
346 372
347 - 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
348 379 $fields_by_repeater_id = array();
349 380 $repeater_ids = array();
350 381
351 382 foreach ( self::$fields as $col ) {
@@ -384,24 +415,26 @@
384 415 }
385 416 unset( $start, $end, $length, $row, $repeater_meta, $where );
386 417
387 418 $flat = array();
419 +
388 420 foreach ( $headings as $key => $heading ) {
389 - if ( is_array( $heading ) ) {
390 - $repeater_id = str_replace( 'repeater', '', $key );
421 + if ( ! is_array( $heading ) ) {
422 + $flat[ $key ] = $heading;
423 + continue;
424 + }
391 425
392 - $repeater_headings = array();
393 - foreach ( $fields_by_repeater_id[ $repeater_id ] as $col ) {
394 - $repeater_headings += self::field_headings( $col );
395 - }
426 + $repeater_id = str_replace( 'repeater', '', $key );
427 + $repeater_headings = array();
396 428
397 - for ( $i = 0; $i < $max[ $repeater_id ]; $i++ ) {
398 - foreach ( $repeater_headings as $repeater_key => $repeater_name ) {
399 - $flat[ $repeater_key . '[' . $i . ']' ] = $repeater_name;
400 - }
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;
401 436 }
402 - } else {
403 - $flat[ $key ] = $heading;
404 437 }
405 438 }
406 439
407 440 self::$fields_by_repeater_id = $fields_by_repeater_id;
@@ -428,8 +461,9 @@
428 461 $headings['is_draft'] = __( 'Entry Status', 'formidable' );
429 462 $headings['ip'] = __( 'IP', 'formidable' );
430 463 $headings['id'] = __( 'ID', 'formidable' );
431 464 $headings['item_key'] = __( 'Key', 'formidable' );
465 +
432 466 if ( self::has_parent_id() ) {
433 467 $headings['parent_id'] = __( 'Parent ID', 'formidable' );
434 468 }
435 469
@@ -437,8 +471,9 @@
437 471 }
438 472
439 473 /**
440 474 * @param object $field
475 + *
441 476 * @return bool
442 477 */
443 478 private static function is_the_child_of_a_repeater( $field ) {
444 479 if ( $field->form_id === self::$form_id || empty( $field->field_options['in_section'] ) ) {
@@ -447,22 +482,26 @@
447 482
448 483 $section_id = $field->field_options['in_section'];
449 484 $section = FrmField::getOne( $section_id );
450 485
451 - if ( ! $section ) {
452 - return false;
453 - }
454 -
455 - return FrmField::is_repeating_field( $section );
486 + return $section && FrmField::is_repeating_field( $section );
456 487 }
457 488
489 + /**
490 + * @return bool
491 + */
458 492 private static function has_parent_id() {
459 493 return self::$has_parent_id;
460 494 }
461 495
496 + /**
497 + * @param array $next_set
498 + *
499 + * @return void
500 + */
462 501 private static function prepare_next_csv_rows( $next_set ) {
463 502 if ( FrmAppHelper::pro_is_installed() ) {
464 - $where = array(
503 + $where = array(
465 504 'or' => 1,
466 505 'id' => $next_set,
467 506 'parent_item_id' => $next_set,
468 507 );
@@ -469,9 +508,9 @@
469 508 // Order by parent_item_id so children will be first.
470 509 $order_by = ' ORDER BY parent_item_id DESC';
471 510 } else {
472 511 // When Pro is not installed, only query for direct ID matches only as we do not expect parent item id
473 - // matches and the more simplified query is faster.
512 + // Matches and the more simplified query is faster.
474 513 $where = array(
475 514 'id' => $next_set,
476 515 );
477 516 $order_by = '';
@@ -482,16 +521,19 @@
482 521 foreach ( $entries as $entry ) {
483 522 self::$entry = $entry;
484 523 unset( $entry );
485 524
486 - if ( self::$entry->form_id !== self::$form_id ) {
525 + if ( self::$entry->form_id === self::$form_id ) {
526 + self::prepare_csv_row();
527 + } else {
487 528 self::add_repeat_field_values_to_csv( $entries );
488 - } else {
489 - self::prepare_csv_row();
490 529 }
491 530 }
492 531 }
493 532
533 + /**
534 + * @return void
535 + */
494 536 private static function prepare_csv_row() {
495 537 $row = array();
496 538 self::add_field_values_to_csv( $row );
497 539 self::add_entry_data_to_csv( $row );
@@ -507,15 +549,20 @@
507 549 );
508 550 self::print_csv_row( $row );
509 551 }
510 552
553 + /**
554 + * @param array $entries
555 + *
556 + * @return void
557 + */
511 558 private static function add_repeat_field_values_to_csv( &$entries ) {
512 559 if ( isset( self::$entry->metas ) ) {
513 - // add child entries to the parent
560 + // Add child entries to the parent
514 561 foreach ( self::$entry->metas as $meta_id => $meta_value ) {
515 562 if ( ! is_numeric( $meta_id ) || '' === $meta_value ) {
516 - // if the hook is being used to include field keys in the metas array,
517 - // 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
518 565 continue;
519 566 }
520 567
521 568 if ( ! isset( $entries[ self::$entry->parent_item_id ] ) ) {
@@ -525,10 +572,10 @@
525 572
526 573 if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) {
527 574 $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] = array();
528 575 } elseif ( ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) {
529 - // if the data is here, it should be an array but if this field has collected data
530 - // 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.
531 578 $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] = (array) $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ];
532 579 }
533 580
534 581 // Add the repeated values.
@@ -538,12 +585,13 @@
538 585 self::$entry->metas = self::fill_missing_repeater_metas( self::$entry->metas, $entries );
539 586 $entries[ self::$entry->parent_item_id ]->metas += self::$entry->metas;
540 587 }//end if
541 588
542 - // add the embedded form id
589 + // Add the embedded form id
543 590 if ( ! isset( $entries[ self::$entry->parent_item_id ]->embedded_fields ) ) {
544 591 $entries[ self::$entry->parent_item_id ]->embedded_fields = array();
545 592 }
593 +
546 594 $entries[ self::$entry->parent_item_id ]->embedded_fields[ self::$entry->id ] = self::$entry->form_id;
547 595 }
548 596
549 597 /**
@@ -551,14 +599,14 @@
551 599 * The export needs all of the meta to be filled in, so we put blank strings for every missing repeater child
552 600 *
553 601 * @param array $metas
554 602 * @param array $entries
603 + *
555 604 * @return array
556 605 */
557 606 private static function fill_missing_repeater_metas( $metas, &$entries ) {
558 - $field_ids = array_keys( $metas );
559 - $field_id = end( $field_ids );
560 - $field = self::get_field( $field_id );
607 + $field_id = array_key_last( $metas );
608 + $field = self::get_field( $field_id );
561 609
562 610 if ( ! $field || empty( $field->field_options['in_section'] ) ) {
563 611 return $metas;
564 612 }
@@ -563,37 +611,52 @@
563 611 return $metas;
564 612 }
565 613
566 614 $repeater_id = $field->field_options['in_section'];
615 +
567 616 if ( ! isset( self::$fields_by_repeater_id[ $repeater_id ] ) ) {
568 617 return $metas;
569 618 }
570 619
571 620 foreach ( self::$fields_by_repeater_id[ $repeater_id ] as $repeater_child ) {
572 - if ( ! isset( $metas[ $repeater_child->id ] ) ) {
573 - $metas[ $repeater_child->id ] = '';
621 + if ( isset( $metas[ $repeater_child->id ] ) ) {
622 + continue;
623 + }
574 624
575 - if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) || ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) ) {
576 - $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] = array();
577 - }
625 + $metas[ $repeater_child->id ] = '';
578 626
579 - $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();
580 629 }
630 +
631 + $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ][] = '';
581 632 }
582 633
583 634 return $metas;
584 635 }
585 636
637 + /**
638 + * @param int|string $field_id
639 + *
640 + * @return false|object
641 + */
586 642 private static function get_field( $field_id ) {
587 643 $field_id = (int) $field_id;
644 +
588 645 foreach ( self::$fields as $field ) {
589 646 if ( $field_id === (int) $field->id ) {
590 647 return $field;
591 648 }
592 649 }
650 +
593 651 return false;
594 652 }
595 653
654 + /**
655 + * @param array $row
656 + *
657 + * @return void
658 + */
596 659 private static function add_field_values_to_csv( &$row ) {
597 660 foreach ( self::$fields as $col ) {
598 661 $field_value = self::$entry->metas[ $col->id ] ?? false;
599 662
@@ -612,8 +675,9 @@
612 675 );
613 676
614 677 if ( ! empty( $col->field_options['separate_value'] ) ) {
615 678 $label_key = $col->id . '_label';
679 +
616 680 if ( self::is_the_child_of_a_repeater( $col ) ) {
617 681 $row[ $label_key ] = array();
618 682
619 683 if ( is_array( $field_value ) ) {
@@ -637,8 +701,9 @@
637 701 * @since 5.0.06
638 702 *
639 703 * @param mixed $field_value
640 704 * @param stdClass $field
705 + *
641 706 * @return string
642 707 */
643 708 private static function get_separate_value_label( $field_value, $field ) {
644 709 return FrmEntriesHelper::display_value(
@@ -649,9 +714,9 @@
649 714 'post_id' => self::$entry->post_id,
650 715 'show_icon' => false,
651 716 'entry_id' => self::$entry->id,
652 717 'sep' => self::$separator,
653 - '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
654 719 )
655 720 );
656 721 }
657 722
@@ -656,32 +721,46 @@
656 721 }
657 722
658 723 /**
659 724 * @since 2.0.23
725 + *
726 + * @param array $row
727 + * @param array $atts
728 + *
729 + * @return void
660 730 */
661 731 private static function add_array_values_to_columns( &$row, $atts ) {
662 - if ( is_array( $atts['field_value'] ) ) {
663 - foreach ( $atts['field_value'] as $key => $sub_value ) {
664 - if ( is_array( $sub_value ) ) {
665 - // This is combo field inside repeater. The heading key has this format: [86_first[0]].
666 - foreach ( $sub_value as $sub_key => $sub_sub_value ) {
667 - $column_key = $atts['col']->id . '_' . $sub_key . '[' . $key . ']';
668 - if ( ! is_numeric( $sub_key ) && isset( self::$headings[ $column_key ] ) ) {
669 - $row[ $column_key ] = $sub_sub_value;
670 - }
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;
671 744 }
745 + }
672 746
673 - continue;
674 - }
747 + continue;
748 + }
675 749
676 - $column_key = $atts['col']->id . '_' . $key;
677 - if ( ! is_numeric( $key ) && isset( self::$headings[ $column_key ] ) ) {
678 - $row[ $column_key ] = $sub_value;
679 - }
750 + $column_key = $atts['col']->id . '_' . $key;
751 +
752 + if ( ! is_numeric( $key ) && isset( self::$headings[ $column_key ] ) ) {
753 + $row[ $column_key ] = $sub_value;
680 754 }
681 755 }
682 756 }
683 757
758 + /**
759 + * @param array $row
760 + *
761 + * @return void
762 + */
684 763 private static function add_entry_data_to_csv( &$row ) {
685 764 $row['created_at'] = FrmAppHelper::get_formatted_time( self::$entry->created_at, self::$wp_date_format, ' ' );
686 765 $row['updated_at'] = FrmAppHelper::get_formatted_time( self::$entry->updated_at, self::$wp_date_format, ' ' );
687 766 $row['user_id'] = self::$entry->user_id;
@@ -689,13 +768,19 @@
689 768 $row['is_draft'] = self::$entry->is_draft;
690 769 $row['ip'] = self::$entry->ip;
691 770 $row['id'] = self::$entry->id;
692 771 $row['item_key'] = self::$entry->item_key;
772 +
693 773 if ( self::has_parent_id() ) {
694 774 $row['parent_id'] = self::$entry->parent_item_id;
695 775 }
696 776 }
697 777
778 + /**
779 + * @param array $rows
780 + *
781 + * @return void
782 + */
698 783 private static function print_csv_row( $rows ) {
699 784 $sep = '';
700 785 $echo = 'echo' === self::$mode;
701 786
@@ -703,8 +788,9 @@
703 788 if ( isset( $rows[ $k ] ) ) {
704 789 $row = $rows[ $k ];
705 790 } else {
706 791 $row = '';
792 +
707 793 // array indexed data is not at $rows[ $k ]
708 794 if ( $k[ strlen( $k ) - 1 ] === ']' ) {
709 795 $start = strrpos( $k, '[' );
710 796 $key = substr( $k, 0, $start++ );
@@ -718,13 +804,14 @@
718 804 }
719 805 }
720 806
721 807 if ( is_array( $row ) ) {
722 - // implode the repeated field values
808 + // Implode the repeated field values
723 809 $row = implode( self::$separator, FrmAppHelper::array_flatten( $row, 'reset' ) );
724 810 }
725 811
726 812 $val = self::encode_value( $row );
813 +
727 814 if ( 'return' !== self::$line_break ) {
728 815 $val = str_replace( array( "\r\n", "\r", "\n" ), self::$line_break, $val );
729 816 }
730 817
@@ -732,12 +819,14 @@
732 819 echo $sep . '"' . $val . '"'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
733 820 } else {
734 821 fwrite( self::$fp, $sep . '"' . $val . '"' );
735 822 }
823 +
736 824 $sep = self::$column_separator;
737 825
738 826 unset( $k, $row );
739 827 }//end foreach
828 +
740 829 if ( $echo ) {
741 830 echo "\n";
742 831 } else {
743 832 fwrite( self::$fp, "\n" );
@@ -743,8 +832,13 @@
743 832 fwrite( self::$fp, "\n" );
744 833 }
745 834 }
746 835
836 + /**
837 + * @param string $line
838 + *
839 + * @return string
840 + */
747 841 public static function encode_value( $line ) {
748 842 if ( '' === $line ) {
749 843 return $line;
750 844 }
@@ -752,12 +846,12 @@
752 846 $convmap = false;
753 847
754 848 switch ( self::$to_encoding ) {
755 849 case 'macintosh':
756 - // 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
757 851 // Reference:
758 852 // http://www.alanwood.net/demos/macroman.html.
759 - $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
760 854 break;
761 855 case 'ISO-8859-1':
762 856 $convmap = array( 256, 10000, 0, 0xffff );
763 857 }
@@ -776,9 +870,11 @@
776 870 /**
777 871 * Escape a " in a csv with another "
778 872 *
779 873 * @since 2.0
874 + *
780 875 * @param mixed $value
876 + *
781 877 * @return mixed
782 878 */
783 879 public static function escape_csv( $value ) {
784 880 if ( ! is_string( $value ) ) {
@@ -788,9 +884,8 @@
788 884 if ( '=' === $value[0] ) {
789 885 // escape the = to prevent vulnerability
790 886 $value = "'" . $value;
791 887 }
792 - $value = str_replace( '"', '""', $value );
793 888
794 - return $value;
889 + return str_replace( '"', '""', $value );
795 890 }
796 891 }