| @@ -118,11 +118,9 @@ | ||
| 118 | 118 | if ( ! $on_global_settings_page ) { |
| 119 | 119 | array_splice( $formats, 1, 0, 'UTF-8 with BOM' ); |
| 120 | 120 | } |
| 121 | 121 | |
| 122 | - $formats = apply_filters( 'frm_csv_format_options', $formats ); | |
| 123 | - | |
| 124 | - return $formats; | |
| 122 | + return apply_filters( 'frm_csv_format_options', $formats ); | |
| 125 | 123 | } |
| 126 | 124 | |
| 127 | 125 | /** |
| 128 | 126 | * @param array $atts |
| @@ -156,9 +154,9 @@ | ||
| 156 | 154 | } |
| 157 | 155 | |
| 158 | 156 | unset( $filename ); |
| 159 | 157 | |
| 160 | - $comment_count = FrmDb::get_count( | |
| 158 | + self::$comment_count = FrmDb::get_count( | |
| 161 | 159 | 'frm_item_metas', |
| 162 | 160 | array( |
| 163 | 161 | 'item_id' => $atts['entry_ids'], |
| 164 | 162 | 'field_id' => 0, |
| @@ -169,9 +167,8 @@ | ||
| 169 | 167 | 'order_by' => 'count(*) DESC', |
| 170 | 168 | 'limit' => 1, |
| 171 | 169 | ) |
| 172 | 170 | ); |
| 173 | - self::$comment_count = $comment_count; | |
| 174 | 171 | |
| 175 | 172 | self::prepare_csv_headings(); |
| 176 | 173 | |
| 177 | 174 | /** |
| @@ -257,9 +254,10 @@ | ||
| 257 | 254 | self::$wp_date_format = apply_filters( 'frm_csv_date_format', self::$wp_date_format, $args ); |
| 258 | 255 | self::get_csv_format(); |
| 259 | 256 | self::$charset = get_option( 'blog_charset' ); |
| 260 | 257 | |
| 261 | - $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; | |
| 262 | 260 | |
| 263 | 261 | self::$column_separator = apply_filters( 'frm_csv_column_sep', $col_sep, $args ); |
| 264 | 262 | } |
| 265 | 263 | |
| @@ -361,9 +359,9 @@ | ||
| 361 | 359 | } else { |
| 362 | 360 | $field_headings[ $col->id ] = strip_tags( $col->name ); |
| 363 | 361 | } |
| 364 | 362 | |
| 365 | - $field_headings = apply_filters( | |
| 363 | + return apply_filters( | |
| 366 | 364 | 'frm_csv_field_columns', |
| 367 | 365 | $field_headings, |
| 368 | 366 | array_merge( |
| 369 | 367 | self::get_standard_filter_args(), |
| @@ -369,10 +367,8 @@ | ||
| 369 | 367 | self::get_standard_filter_args(), |
| 370 | 368 | array( 'field' => $col ) |
| 371 | 369 | ) |
| 372 | 370 | ); |
| 373 | - | |
| 374 | - return $field_headings; | |
| 375 | 371 | } |
| 376 | 372 | |
| 377 | 373 | /** |
| 378 | 374 | * @param array $headings |
| @@ -378,9 +374,9 @@ | ||
| 378 | 374 | * @param array $headings |
| 379 | 375 | * |
| 380 | 376 | * @return void |
| 381 | 377 | */ |
| 382 | - private static function csv_headings( &$headings ) { | |
| 378 | + private static function csv_headings( &$headings ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh | |
| 383 | 379 | $fields_by_repeater_id = array(); |
| 384 | 380 | $repeater_ids = array(); |
| 385 | 381 | |
| 386 | 382 | foreach ( self::$fields as $col ) { |
| @@ -421,24 +417,24 @@ | ||
| 421 | 417 | |
| 422 | 418 | $flat = array(); |
| 423 | 419 | |
| 424 | 420 | foreach ( $headings as $key => $heading ) { |
| 425 | - if ( is_array( $heading ) ) { | |
| 426 | - $repeater_id = str_replace( 'repeater', '', $key ); | |
| 421 | + if ( ! is_array( $heading ) ) { | |
| 422 | + $flat[ $key ] = $heading; | |
| 423 | + continue; | |
| 424 | + } | |
| 427 | 425 | |
| 428 | - $repeater_headings = array(); | |
| 426 | + $repeater_id = str_replace( 'repeater', '', $key ); | |
| 427 | + $repeater_headings = array(); | |
| 429 | 428 | |
| 430 | - foreach ( $fields_by_repeater_id[ $repeater_id ] as $col ) { | |
| 431 | - $repeater_headings += self::field_headings( $col ); | |
| 432 | - } | |
| 429 | + foreach ( $fields_by_repeater_id[ $repeater_id ] as $col ) { | |
| 430 | + $repeater_headings += self::field_headings( $col ); | |
| 431 | + } | |
| 433 | 432 | |
| 434 | - for ( $i = 0; $i < $max[ $repeater_id ]; $i++ ) { | |
| 435 | - foreach ( $repeater_headings as $repeater_key => $repeater_name ) { | |
| 436 | - $flat[ $repeater_key . '[' . $i . ']' ] = $repeater_name; | |
| 437 | - } | |
| 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; | |
| 438 | 436 | } |
| 439 | - } else { | |
| 440 | - $flat[ $key ] = $heading; | |
| 441 | 437 | } |
| 442 | 438 | } |
| 443 | 439 | |
| 444 | 440 | self::$fields_by_repeater_id = $fields_by_repeater_id; |
| @@ -486,13 +482,9 @@ | ||
| 486 | 482 | |
| 487 | 483 | $section_id = $field->field_options['in_section']; |
| 488 | 484 | $section = FrmField::getOne( $section_id ); |
| 489 | 485 | |
| 490 | - if ( ! $section ) { | |
| 491 | - return false; | |
| 492 | - } | |
| 493 | - | |
| 494 | - return FrmField::is_repeating_field( $section ); | |
| 486 | + return $section && FrmField::is_repeating_field( $section ); | |
| 495 | 487 | } |
| 496 | 488 | |
| 497 | 489 | /** |
| 498 | 490 | * @return bool |
| @@ -507,9 +499,9 @@ | ||
| 507 | 499 | * @return void |
| 508 | 500 | */ |
| 509 | 501 | private static function prepare_next_csv_rows( $next_set ) { |
| 510 | 502 | if ( FrmAppHelper::pro_is_installed() ) { |
| 511 | - $where = array( | |
| 503 | + $where = array( | |
| 512 | 504 | 'or' => 1, |
| 513 | 505 | 'id' => $next_set, |
| 514 | 506 | 'parent_item_id' => $next_set, |
| 515 | 507 | ); |
| @@ -516,9 +508,9 @@ | ||
| 516 | 508 | // Order by parent_item_id so children will be first. |
| 517 | 509 | $order_by = ' ORDER BY parent_item_id DESC'; |
| 518 | 510 | } else { |
| 519 | 511 | // When Pro is not installed, only query for direct ID matches only as we do not expect parent item id |
| 520 | - // matches and the more simplified query is faster. | |
| 512 | + // Matches and the more simplified query is faster. | |
| 521 | 513 | $where = array( |
| 522 | 514 | 'id' => $next_set, |
| 523 | 515 | ); |
| 524 | 516 | $order_by = ''; |
| @@ -529,12 +521,12 @@ | ||
| 529 | 521 | foreach ( $entries as $entry ) { |
| 530 | 522 | self::$entry = $entry; |
| 531 | 523 | unset( $entry ); |
| 532 | 524 | |
| 533 | - if ( self::$entry->form_id !== self::$form_id ) { | |
| 525 | + if ( self::$entry->form_id === self::$form_id ) { | |
| 526 | + self::prepare_csv_row(); | |
| 527 | + } else { | |
| 534 | 528 | self::add_repeat_field_values_to_csv( $entries ); |
| 535 | - } else { | |
| 536 | - self::prepare_csv_row(); | |
| 537 | 529 | } |
| 538 | 530 | } |
| 539 | 531 | } |
| 540 | 532 | |
| @@ -564,13 +556,13 @@ | ||
| 564 | 556 | * @return void |
| 565 | 557 | */ |
| 566 | 558 | private static function add_repeat_field_values_to_csv( &$entries ) { |
| 567 | 559 | if ( isset( self::$entry->metas ) ) { |
| 568 | - // add child entries to the parent | |
| 560 | + // Add child entries to the parent | |
| 569 | 561 | foreach ( self::$entry->metas as $meta_id => $meta_value ) { |
| 570 | 562 | if ( ! is_numeric( $meta_id ) || '' === $meta_value ) { |
| 571 | - // if the hook is being used to include field keys in the metas array, | |
| 572 | - // 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 | |
| 573 | 565 | continue; |
| 574 | 566 | } |
| 575 | 567 | |
| 576 | 568 | if ( ! isset( $entries[ self::$entry->parent_item_id ] ) ) { |
| @@ -580,10 +572,10 @@ | ||
| 580 | 572 | |
| 581 | 573 | if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) { |
| 582 | 574 | $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] = array(); |
| 583 | 575 | } elseif ( ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] ) ) { |
| 584 | - // if the data is here, it should be an array but if this field has collected data | |
| 585 | - // 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. | |
| 586 | 578 | $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ] = (array) $entries[ self::$entry->parent_item_id ]->metas[ $meta_id ]; |
| 587 | 579 | } |
| 588 | 580 | |
| 589 | 581 | // Add the repeated values. |
| @@ -593,12 +585,13 @@ | ||
| 593 | 585 | self::$entry->metas = self::fill_missing_repeater_metas( self::$entry->metas, $entries ); |
| 594 | 586 | $entries[ self::$entry->parent_item_id ]->metas += self::$entry->metas; |
| 595 | 587 | }//end if |
| 596 | 588 | |
| 597 | - // add the embedded form id | |
| 589 | + // Add the embedded form id | |
| 598 | 590 | if ( ! isset( $entries[ self::$entry->parent_item_id ]->embedded_fields ) ) { |
| 599 | 591 | $entries[ self::$entry->parent_item_id ]->embedded_fields = array(); |
| 600 | 592 | } |
| 593 | + | |
| 601 | 594 | $entries[ self::$entry->parent_item_id ]->embedded_fields[ self::$entry->id ] = self::$entry->form_id; |
| 602 | 595 | } |
| 603 | 596 | |
| 604 | 597 | /** |
| @@ -610,11 +603,10 @@ | ||
| 610 | 603 | * |
| 611 | 604 | * @return array |
| 612 | 605 | */ |
| 613 | 606 | private static function fill_missing_repeater_metas( $metas, &$entries ) { |
| 614 | - $field_ids = array_keys( $metas ); | |
| 615 | - $field_id = end( $field_ids ); | |
| 616 | - $field = self::get_field( $field_id ); | |
| 607 | + $field_id = array_key_last( $metas ); | |
| 608 | + $field = self::get_field( $field_id ); | |
| 617 | 609 | |
| 618 | 610 | if ( ! $field || empty( $field->field_options['in_section'] ) ) { |
| 619 | 611 | return $metas; |
| 620 | 612 | } |
| @@ -625,17 +617,19 @@ | ||
| 625 | 617 | return $metas; |
| 626 | 618 | } |
| 627 | 619 | |
| 628 | 620 | foreach ( self::$fields_by_repeater_id[ $repeater_id ] as $repeater_child ) { |
| 629 | - if ( ! isset( $metas[ $repeater_child->id ] ) ) { | |
| 630 | - $metas[ $repeater_child->id ] = ''; | |
| 621 | + if ( isset( $metas[ $repeater_child->id ] ) ) { | |
| 622 | + continue; | |
| 623 | + } | |
| 631 | 624 | |
| 632 | - if ( ! isset( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) || ! is_array( $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] ) ) { | |
| 633 | - $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ] = array(); | |
| 634 | - } | |
| 625 | + $metas[ $repeater_child->id ] = ''; | |
| 635 | 626 | |
| 636 | - $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(); | |
| 637 | 629 | } |
| 630 | + | |
| 631 | + $entries[ self::$entry->parent_item_id ]->metas[ $repeater_child->id ][] = ''; | |
| 638 | 632 | } |
| 639 | 633 | |
| 640 | 634 | return $metas; |
| 641 | 635 | } |
| @@ -652,8 +646,9 @@ | ||
| 652 | 646 | if ( $field_id === (int) $field->id ) { |
| 653 | 647 | return $field; |
| 654 | 648 | } |
| 655 | 649 | } |
| 650 | + | |
| 656 | 651 | return false; |
| 657 | 652 | } |
| 658 | 653 | |
| 659 | 654 | /** |
| @@ -719,9 +714,9 @@ | ||
| 719 | 714 | 'post_id' => self::$entry->post_id, |
| 720 | 715 | 'show_icon' => false, |
| 721 | 716 | 'entry_id' => self::$entry->id, |
| 722 | 717 | 'sep' => self::$separator, |
| 723 | - '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 | |
| 724 | 719 | ) |
| 725 | 720 | ); |
| 726 | 721 | } |
| 727 | 722 | |
| @@ -733,30 +728,32 @@ | ||
| 733 | 728 | * |
| 734 | 729 | * @return void |
| 735 | 730 | */ |
| 736 | 731 | private static function add_array_values_to_columns( &$row, $atts ) { |
| 737 | - if ( is_array( $atts['field_value'] ) ) { | |
| 738 | - foreach ( $atts['field_value'] as $key => $sub_value ) { | |
| 739 | - if ( is_array( $sub_value ) ) { | |
| 740 | - // This is combo field inside repeater. The heading key has this format: [86_first[0]]. | |
| 741 | - foreach ( $sub_value as $sub_key => $sub_sub_value ) { | |
| 742 | - $column_key = $atts['col']->id . '_' . $sub_key . '[' . $key . ']'; | |
| 732 | + if ( ! is_array( $atts['field_value'] ) ) { | |
| 733 | + return; | |
| 734 | + } | |
| 743 | 735 | |
| 744 | - if ( ! is_numeric( $sub_key ) && isset( self::$headings[ $column_key ] ) ) { | |
| 745 | - $row[ $column_key ] = $sub_sub_value; | |
| 746 | - } | |
| 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; | |
| 747 | 744 | } |
| 745 | + } | |
| 748 | 746 | |
| 749 | - continue; | |
| 750 | - } | |
| 747 | + continue; | |
| 748 | + } | |
| 751 | 749 | |
| 752 | - $column_key = $atts['col']->id . '_' . $key; | |
| 750 | + $column_key = $atts['col']->id . '_' . $key; | |
| 753 | 751 | |
| 754 | - if ( ! is_numeric( $key ) && isset( self::$headings[ $column_key ] ) ) { | |
| 755 | - $row[ $column_key ] = $sub_value; | |
| 756 | - } | |
| 752 | + if ( ! is_numeric( $key ) && isset( self::$headings[ $column_key ] ) ) { | |
| 753 | + $row[ $column_key ] = $sub_value; | |
| 757 | 754 | } |
| 758 | - }//end if | |
| 755 | + } | |
| 759 | 756 | } |
| 760 | 757 | |
| 761 | 758 | /** |
| 762 | 759 | * @param array $row |
| @@ -807,9 +804,9 @@ | ||
| 807 | 804 | } |
| 808 | 805 | } |
| 809 | 806 | |
| 810 | 807 | if ( is_array( $row ) ) { |
| 811 | - // implode the repeated field values | |
| 808 | + // Implode the repeated field values | |
| 812 | 809 | $row = implode( self::$separator, FrmAppHelper::array_flatten( $row, 'reset' ) ); |
| 813 | 810 | } |
| 814 | 811 | |
| 815 | 812 | $val = self::encode_value( $row ); |
| @@ -849,12 +846,12 @@ | ||
| 849 | 846 | $convmap = false; |
| 850 | 847 | |
| 851 | 848 | switch ( self::$to_encoding ) { |
| 852 | 849 | case 'macintosh': |
| 853 | - // 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 | |
| 854 | 851 | // Reference: |
| 855 | 852 | // http://www.alanwood.net/demos/macroman.html. |
| 856 | - $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 | |
| 857 | 854 | break; |
| 858 | 855 | case 'ISO-8859-1': |
| 859 | 856 | $convmap = array( 256, 10000, 0, 0xffff ); |
| 860 | 857 | } |
| @@ -888,9 +885,7 @@ | ||
| 888 | 885 | // escape the = to prevent vulnerability |
| 889 | 886 | $value = "'" . $value; |
| 890 | 887 | } |
| 891 | 888 | |
| 892 | - $value = str_replace( '"', '""', $value ); | |
| 893 | - | |
| 894 | - return $value; | |
| 889 | + return str_replace( '"', '""', $value ); | |
| 895 | 890 | } |
| 896 | 891 | } |