PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.26
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.26
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
formidable / classes / controllers / FrmXMLController.php

FrmXMLController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.26, at classes/controllers/FrmXMLController.php

817 lines 21.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmXMLController {
7
8 /**
9 * @return void
10 */
11 public static function menu() {
12 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Import/Export', 'formidable' ), __( 'Import/Export', 'formidable' ), 'frm_edit_forms', 'formidable-import', 'FrmXMLController::route' );
13 }
14
15 /**
16 * @return void
17 */
18 public static function add_default_templates() {
19 if ( FrmXMLHelper::check_if_libxml_disable_entity_loader_exists() ) {
20 // XML import is not enabled on your server.
21 return;
22 }
23
24 $set_err = libxml_use_internal_errors( true );
25 $loader = FrmXMLHelper::maybe_libxml_disable_entity_loader( true );
26
27 $files = apply_filters( 'frm_default_templates_files', array() );
28
29 foreach ( (array) $files as $file ) {
30 FrmXMLHelper::import_xml( $file );
31 unset( $file );
32 }
33
34 unset( $files );
35
36 libxml_use_internal_errors( $set_err );
37 FrmXMLHelper::maybe_libxml_disable_entity_loader( $loader );
38 }
39
40 /**
41 * Use the template link to install the XML template
42 *
43 * @since 3.06
44 *
45 * @return void
46 */
47 public static function install_template() {
48 FrmAppHelper::permission_check( 'frm_edit_forms' );
49 check_ajax_referer( 'frm_ajax', 'nonce' );
50
51 if ( ! function_exists( 'simplexml_load_string' ) ) {
52 $response = array(
53 'message' => __( 'Your server is missing the Simple XML extension. This is required to install a template.', 'formidable' ),
54 );
55 echo wp_json_encode( $response );
56 wp_die();
57 }
58
59 $form = self::get_posted_form();
60 $url = FrmAppHelper::get_param( 'xml', '', 'post', 'esc_url_raw' );
61 self::override_url( $form, $url );
62
63 if ( ! self::validate_xml_url( $url ) ) {
64 $response = array(
65 'message' => __( 'The template you are trying to install could not be validated.', 'formidable' ),
66 );
67 echo wp_json_encode( $response );
68 wp_die();
69 }
70
71 $response = wp_remote_get( $url );
72 $body = wp_remote_retrieve_body( $response );
73 $xml = simplexml_load_string( $body );
74
75 if ( ! $xml ) {
76 $response = array(
77 'message' => __( 'There was an error reading the form template.', 'formidable' ),
78 );
79 echo wp_json_encode( $response );
80 wp_die();
81 }
82
83 self::set_new_form_name( $xml );
84
85 $imported = FrmXMLHelper::import_xml_now( $xml, true );
86
87 if ( ! empty( $imported['form_status'] ) ) {
88 // Get the last form id in case there are child forms.
89 end( $imported['form_status'] );
90 $form_id = key( $imported['form_status'] );
91 $response = array(
92 'id' => $form_id,
93 'redirect' => FrmForm::get_edit_link( $form_id ) . '&new_template=true',
94 'success' => 1,
95 );
96
97 if ( ! empty( $imported['imported']['posts'] ) ) {
98 // Return the link to the last page created.
99 $pages = $imported['posts'];
100 }
101
102 if ( ! empty( $form ) ) {
103 // Create selected pages with the correct shortcodes.
104 $pages = self::create_pages_for_import( $form );
105 }
106
107 if ( ! empty( $pages ) ) {
108 $post_id = end( $pages );
109 $response['redirect'] = get_permalink( $post_id );
110 }
111 } else {
112 if ( isset( $imported['error'] ) ) {
113 $message = $imported['error'];
114 } else {
115 $message = __( 'There was an error importing form', 'formidable' );
116 }
117
118 $response = array(
119 'message' => $message,
120 );
121
122 }//end if
123
124 /**
125 * @since 6.18 Added `url` to the $args.
126 */
127 $response = apply_filters( 'frm_xml_response', $response, compact( 'form', 'imported', 'url' ) );
128
129 echo wp_json_encode( $response );
130 wp_die();
131 }
132
133 /**
134 * Make sure that the XML file we're trying to load is in fact an XML file, and that it's coming from our S3 bucket.
135 * This is to make sure that the URL can't be exploited for a SSRF attack.
136 *
137 * @since 5.5.5
138 *
139 * @param string $url
140 *
141 * @return bool True on success, False on error.
142 */
143 private static function validate_xml_url( $url ) {
144 return FrmAppHelper::validate_url_is_in_s3_bucket( $url, 'xml' );
145 }
146
147 /**
148 * @since 4.06.02
149 *
150 * @return mixed
151 */
152 private static function get_posted_form() {
153 $form = FrmAppHelper::get_param( 'form', '', 'post', 'wp_unslash' );
154
155 if ( empty( $form ) ) {
156 return $form;
157 }
158
159 $form = json_decode( $form, true );
160 return $form;
161 }
162
163 /**
164 * Get a different URL depending on the selection in the form.
165 *
166 * @since 4.06.02
167 *
168 * @param array $form The posted form values.
169 * @param string $url The URL to override.
170 *
171 * @return void
172 */
173 private static function override_url( $form, &$url ) {
174 $selected_form = self::get_selected_in_form( $form, 'form' );
175
176 if ( empty( $selected_form ) ) {
177 return;
178 }
179
180 $selected_xml = isset( $form['xml'] ) && isset( $form['xml'][ $selected_form ] ) ? $form['xml'][ $selected_form ] : '';
181
182 if ( empty( $selected_xml ) || strpos( $selected_xml, 'http' ) !== 0 ) {
183 return;
184 }
185
186 $url = $selected_xml;
187 }
188
189 /**
190 * @since 4.06.02
191 *
192 * @param array $form
193 * @param string $value
194 *
195 * @return string
196 */
197 private static function get_selected_in_form( $form, $value = 'form' ) {
198 if ( ! empty( $form ) && ! empty( $form[ $value ] ) ) {
199 return $form[ $value ];
200 }
201
202 return '';
203 }
204
205 /**
206 * @since 4.06.02
207 *
208 * @param array $form The posted form values.
209 *
210 * @return array|null The array of created pages.
211 */
212 private static function create_pages_for_import( $form ) {
213 if ( empty( $form['pages'] ) ) {
214 return null;
215 }
216
217 $form_key = self::get_selected_in_form( $form, 'form' );
218 $view_keys = self::get_selected_in_form( $form, 'view' );
219
220 $page_ids = array();
221
222 foreach ( (array) $form['pages'] as $for => $name ) {
223 if ( empty( $name ) ) {
224 // Don't create a page if no title is given.
225 continue;
226 }
227
228 if ( $for === 'view' ) {
229 $item_key = is_array( $view_keys ) ? $view_keys[ $form_key ] : $view_keys;
230 $shortcode = '[display-frm-data id=%1$s filter=limited]';
231 } elseif ( $for === 'form' ) {
232 $item_key = $form_key;
233 $shortcode = '[formidable id=%1$s]';
234 } else {
235 $item_key = self::get_selected_in_form( $form, 'form' );
236 $shortcode = '[' . esc_html( $for ) . ' id=%1$s]';
237 }
238
239 if ( empty( $item_key ) ) {
240 // Don't create it if the shortcode won't show anything.
241 continue;
242 }
243
244 $page_ids[ $for ] = wp_insert_post(
245 array(
246 'post_title' => $name,
247 'post_type' => 'page',
248 'post_content' => sprintf( $shortcode, $item_key ),
249 )
250 );
251 }//end foreach
252
253 return $page_ids;
254 }
255
256 /**
257 * Change the name of the last form that is not a child.
258 * This will allow for lookup fields and embedded forms
259 * since we redirect to the last form.
260 *
261 * @since 3.06
262 *
263 * @param object $xml The values included in the XML.
264 *
265 * @return void
266 */
267 private static function set_new_form_name( &$xml ) {
268 if ( ! isset( $xml->form ) ) {
269 return;
270 }
271
272 $name = FrmAppHelper::get_param( 'name', '', 'post', 'sanitize_text_field' );
273 $description = FrmAppHelper::get_param( 'desc', '', 'post', 'sanitize_textarea_field' );
274
275 if ( ! $name && ! $description ) {
276 return;
277 }
278
279 // Get the main form ID.
280 $set_name = 0;
281
282 foreach ( $xml->form as $form ) {
283 if ( empty( $form->parent_form_id ) ) {
284 $set_name = (int) $form->id;
285 }
286 }
287
288 foreach ( $xml->form as $form ) {
289 // Maybe set the form name if this isn't a child form.
290 if ( $set_name === (int) $form->id ) {
291 $form->name = $name;
292 $form->description = $description;
293 }
294
295 // Use a unique key to prevent editing existing form.
296 $sanitized_form_name = sanitize_title( $form->name );
297 $form->form_key = FrmAppHelper::get_unique_key( $sanitized_form_name, 'frm_forms', 'form_key' );
298 }
299 }
300
301 /**
302 * @return void
303 */
304 public static function route() {
305 $action = isset( $_REQUEST['frm_action'] ) ? 'frm_action' : 'action';
306 $action = FrmAppHelper::get_param( $action, '', 'get', 'sanitize_title' );
307 FrmAppHelper::include_svg();
308
309 if ( 'import_xml' === $action ) {
310 self::import_xml();
311 } elseif ( 'export_xml' === $action ) {
312 self::export_xml();
313 } elseif ( apply_filters( 'frm_xml_route', true, $action ) ) {
314 self::form();
315 }
316 }
317
318 /**
319 * @param string[] $errors
320 * @param string $message
321 *
322 * @return void
323 */
324 public static function form( $errors = array(), $message = '' ) {
325 $where = array(
326 'status' => array( null, '', 'published' ),
327 );
328 $forms = FrmForm::getAll( $where, 'name' );
329
330 $export_types = array(
331 'forms' => __( 'Forms', 'formidable' ),
332 'items' => __( 'Entries', 'formidable' ),
333 );
334 $export_types = apply_filters( 'frm_xml_export_types', $export_types );
335
336 $export_format = array(
337 'xml' => array(
338 'name' => 'XML',
339 'support' => 'forms',
340 'count' => 'multiple',
341 ),
342 'csv' => array(
343 'name' => 'CSV',
344 'support' => 'items',
345 'count' => 'single',
346 ),
347 );
348 $export_format = apply_filters( 'frm_export_formats', $export_format );
349
350 include FrmAppHelper::plugin_path() . '/classes/views/xml/import_form.php';
351 }
352
353 /**
354 * @return void
355 */
356 public static function import_xml() {
357 $errors = array();
358 $message = '';
359
360 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'import-xml', 'import-xml-nonce' );
361
362 if ( false !== $permission_error ) {
363 $errors[] = $permission_error;
364 self::form( $errors );
365
366 return;
367 }
368
369 // phpcs:ignore WordPress.Security.NonceVerification.Missing
370 $has_file = ! empty( $_FILES['frm_import_file'] ) && ! empty( $_FILES['frm_import_file']['name'] ) && ! empty( $_FILES['frm_import_file']['size'] ) && (int) $_FILES['frm_import_file']['size'] > 0;
371
372 if ( ! $has_file ) {
373 $errors[] = __( 'Oops, you didn\'t select a file.', 'formidable' );
374 self::form( $errors );
375
376 return;
377 }
378
379 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Missing
380 $file = isset( $_FILES['frm_import_file']['tmp_name'] ) ? sanitize_option( 'upload_path', $_FILES['frm_import_file']['tmp_name'] ) : '';
381
382 if ( ! is_uploaded_file( $file ) ) {
383 unset( $file );
384 $errors[] = __( 'The file does not exist, please try again.', 'formidable' );
385 self::form( $errors );
386
387 return;
388 }
389
390 $export_format = array(
391 'xml' => array(
392 'name' => 'XML',
393 'support' => 'forms',
394 'count' => 'multiple',
395 ),
396 );
397 $export_format = apply_filters( 'frm_export_formats', $export_format );
398
399 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Missing
400 $file_type = sanitize_option( 'upload_path', $_FILES['frm_import_file']['name'] );
401 $file_type = strtolower( pathinfo( $file_type, PATHINFO_EXTENSION ) );
402
403 if ( 'xml' !== $file_type && isset( $export_format[ $file_type ] ) ) {
404 // allow other file types to be imported
405 do_action( 'frm_before_import_' . $file_type );
406
407 return;
408 }
409 unset( $file_type );
410
411 if ( FrmXMLHelper::check_if_libxml_disable_entity_loader_exists() ) {
412 $errors[] = __( 'XML import is not enabled on your server with the libxml_disable_entity_loader function.', 'formidable' );
413 self::form( $errors );
414
415 return;
416 }
417
418 $set_err = libxml_use_internal_errors( true );
419 $loader = FrmXMLHelper::maybe_libxml_disable_entity_loader( true );
420
421 $result = FrmXMLHelper::import_xml( $file );
422 FrmXMLHelper::parse_message( $result, $message, $errors );
423
424 unset( $file );
425
426 libxml_use_internal_errors( $set_err );
427 FrmXMLHelper::maybe_libxml_disable_entity_loader( $loader );
428
429 self::form( $errors, $message );
430 }
431
432 /**
433 * @return void
434 */
435 public static function export_xml() {
436 $error = FrmAppHelper::permission_nonce_error( 'frm_edit_forms', 'export-xml', 'export-xml-nonce' );
437
438 if ( ! empty( $error ) ) {
439 wp_die( esc_html( $error ) );
440 }
441
442 $ids = FrmAppHelper::get_post_param( 'frm_export_forms', array(), 'sanitize_text_field' );
443 $type = FrmAppHelper::get_post_param( 'type', array(), 'sanitize_text_field' );
444 $format = FrmAppHelper::get_post_param( 'format', 'xml', 'sanitize_title' );
445
446 if ( ! headers_sent() && ! $type ) {
447 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=formidable-import' ) ) );
448 die();
449 }
450
451 if ( 'xml' === $format ) {
452 self::generate_xml( $type, compact( 'ids' ) );
453 } elseif ( 'csv' === $format ) {
454 self::generate_csv( compact( 'ids' ) );
455 } else {
456 do_action( 'frm_export_format_' . $format, compact( 'ids' ) );
457 }
458
459 wp_die();
460 }
461
462 /**
463 * @param array<string>|string $type
464 * @param array $args
465 *
466 * @psalm-param array{ids?: mixed} $args
467 *
468 * @return void
469 */
470 public static function generate_xml( $type, $args = array() ) {
471 global $wpdb;
472
473 self::prepare_types_array( $type );
474
475 if ( ! is_array( $type ) ) {
476 // This shouldn't be possible.
477 // It is cast to array in prepare_types_array.
478 // This is just for static analysis.
479 return;
480 }
481
482 $tables = array(
483 'items' => $wpdb->prefix . 'frm_items',
484 'forms' => $wpdb->prefix . 'frm_forms',
485 'posts' => $wpdb->posts,
486 'styles' => $wpdb->posts,
487 'actions' => $wpdb->posts,
488 );
489
490 $defaults = array(
491 'ids' => false,
492 );
493 $args = wp_parse_args( $args, $defaults );
494
495 // Make sure ids are numeric.
496 if ( is_array( $args['ids'] ) && ! empty( $args['ids'] ) ) {
497 $args['ids'] = array_filter( $args['ids'], 'is_numeric' );
498 }
499
500 $records = array();
501
502 foreach ( $type as $tb_type ) {
503 $where = array();
504 $join = '';
505 $table = $tables[ $tb_type ];
506
507 $select = $table . '.id';
508 $query_vars = array();
509
510 switch ( $tb_type ) {
511 case 'forms':
512 // Add forms.
513 if ( $args['ids'] ) {
514 $where[] = array(
515 'or' => 1,
516 $table . '.id' => $args['ids'],
517 $table . '.parent_form_id' => $args['ids'],
518 );
519 } else {
520 $where[ $table . '.status !' ] = 'draft';
521 }
522 break;
523 case 'actions':
524 $select = $table . '.ID';
525 $where['post_type'] = FrmFormActionsController::$action_post_type;
526
527 if ( ! empty( $args['ids'] ) ) {
528 $where['menu_order'] = $args['ids'];
529 }
530 break;
531 case 'items':
532 // $join = "INNER JOIN {$wpdb->prefix}frm_item_metas im ON ($table.id = im.item_id)";
533 if ( $args['ids'] ) {
534 $where[ $table . '.form_id' ] = $args['ids'];
535 }
536 break;
537 case 'styles':
538 // Loop through all exported forms and get their selected style IDs.
539 $frm_style = new FrmStyle();
540 $default_style = $frm_style->get_default_style();
541 $form_ids = $args['ids'];
542 $style_ids = array();
543
544 foreach ( $form_ids as $form_id ) {
545 $form_data = FrmForm::getOne( $form_id );
546
547 // For forms that have not been updated while running 2.0, check if custom_style is set.
548 if ( isset( $form_data->options['custom_style'] ) ) {
549 if ( 1 === absint( $form_data->options['custom_style'] ) ) {
550 $style_ids[] = $default_style->ID;
551 } else {
552 $style_ids[] = $form_data->options['custom_style'];
553 }
554 }
555 unset( $form_id, $form_data );
556 }
557
558 $select = $table . '.ID';
559 $where['post_type'] = 'frm_styles';
560
561 // Only export selected styles.
562 if ( ! empty( $style_ids ) ) {
563 $where['ID'] = $style_ids;
564 }
565 break;
566 default:
567 $select = $table . '.ID';
568 $join = ' INNER JOIN ' . $wpdb->postmeta . ' pm ON (pm.post_id=' . $table . '.ID)';
569 $where['pm.meta_key'] = 'frm_form_id';
570
571 if ( empty( $args['ids'] ) ) {
572 $where['pm.meta_value >'] = 1;
573 } else {
574 $where['pm.meta_value'] = $args['ids'];
575 }
576 }//end switch
577
578 $records[ $tb_type ] = FrmDb::get_col( $table . $join, $where, $select );
579 unset( $tb_type );
580 }//end foreach
581
582 $filename = self::get_file_name( $args, $records );
583
584 header( 'Content-Description: File Transfer' );
585 header( 'Content-Disposition: attachment; filename=' . $filename );
586 header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
587
588 echo '<?xml version="1.0" encoding="' . esc_attr( get_bloginfo( 'charset' ) ) . "\" ?>\n";
589 include FrmAppHelper::plugin_path() . '/classes/views/xml/xml.php';
590 }
591
592 /**
593 * Returns an array that has parent term slugs for the terms provided.
594 *
595 * @since 6.8.3
596 *
597 * @param array $terms
598 *
599 * @return array
600 */
601 public static function get_parent_terms_slugs( $terms ) {
602 $parent_term_ids = array_filter( array_unique( wp_list_pluck( $terms, 'parent' ) ) );
603 $parent_slugs = array();
604
605 if ( ! $parent_term_ids ) {
606 return $parent_slugs;
607 }
608
609 $results = FrmDb::get_results( 'terms', array( 'term_id' => $parent_term_ids ), 'term_id, slug' );
610 $parent_slugs = wp_list_pluck( $results, 'slug', 'term_id' );
611
612 return $parent_slugs;
613 }
614
615 /**
616 * Prepare the types array.
617 *
618 * @param array<string>|string $type
619 *
620 * @return void
621 */
622 private static function prepare_types_array( &$type ) {
623 $type = (array) $type;
624
625 if ( ! in_array( 'forms', $type, true ) && ( in_array( 'items', $type, true ) || in_array( 'posts', $type, true ) ) ) {
626 // make sure the form is included if there are entries
627 $type[] = 'forms';
628 }
629
630 if ( in_array( 'forms', $type, true ) ) {
631 // include actions with forms
632 $type[] = 'actions';
633 }
634 }
635
636 /**
637 * Use a generic file name if multiple items are exported.
638 * Use the nme of the form if only one form is exported.
639 *
640 * @since 3.06
641 *
642 * @param array $args
643 * @param array $records
644 *
645 * @return string
646 */
647 private static function get_file_name( $args, $records ) {
648 $has_one_form = ! empty( $records['forms'] ) && count( $args['ids'] ) === 1;
649
650 if ( $has_one_form ) {
651 // one form is being exported
652 $selected_form_id = reset( $args['ids'] );
653 $filename = 'form-' . $selected_form_id . '.xml';
654
655 foreach ( $records['forms'] as $form_id ) {
656 $filename = 'form-' . $form_id . '.xml';
657
658 if ( $selected_form_id === $form_id ) {
659 $form = FrmForm::getOne( $form_id );
660 $filename = $form->name !== '' ? $form->name : $form->form_key;
661 $filename = sanitize_title( $filename ) . '-form.xml';
662 break;
663 }
664 }
665 } else {
666 $sitename = sanitize_key( get_bloginfo( 'name' ) );
667
668 if ( ! empty( $sitename ) ) {
669 $sitename .= '.';
670 }
671
672 $filename = $sitename . 'formidable.' . gmdate( 'Y-m-d' ) . '.xml';
673 }//end if
674
675 /**
676 * @since 5.3
677 *
678 * @param string $filename
679 */
680 return apply_filters( 'frm_xml_filename', $filename );
681 }
682
683 /**
684 * @param array $atts
685 *
686 * @return void
687 */
688 public static function generate_csv( $atts ) {
689 $form_ids = $atts['ids'];
690
691 if ( empty( $form_ids ) ) {
692 wp_die( esc_html__( 'Please select a form', 'formidable' ) );
693 }
694 self::csv( reset( $form_ids ) );
695 }
696
697 /**
698 * Export to CSV
699 *
700 * @since 2.0.19
701 *
702 * @param false|int|string $form_id
703 * @param string $search
704 * @param string $fid
705 *
706 * @return void
707 */
708 public static function csv( $form_id = false, $search = '', $fid = '' ) {
709 FrmAppHelper::permission_check( 'frm_view_entries' );
710
711 if ( ! $form_id ) {
712 $form_id = FrmAppHelper::get_param( 'form', '', 'get', 'sanitize_text_field' );
713 $search = FrmAppHelper::get_param( ( isset( $_REQUEST['s'] ) ? 's' : 'search' ), '', 'get', 'sanitize_text_field' );
714 $fid = FrmAppHelper::get_param( 'fid', '', 'get', 'sanitize_text_field' );
715 }
716
717 // Remove time limit to execute this function.
718 if ( function_exists( 'set_time_limit' ) ) {
719 set_time_limit( 0 );
720 }
721
722 $mem_limit = str_replace( 'M', '', ini_get( 'memory_limit' ) );
723
724 if ( (int) $mem_limit < 256 ) {
725 wp_raise_memory_limit();
726 }
727
728 global $wpdb;
729
730 $form = FrmForm::getOne( $form_id );
731
732 if ( ! $form ) {
733 esc_html_e( 'Form not found.', 'formidable' );
734 wp_die();
735 }
736
737 $form_id = $form->id;
738 $form_cols = self::get_fields_for_csv_export( $form_id, $form );
739
740 $item_id = FrmAppHelper::get_param( 'item_id', 0, 'get', 'sanitize_text_field' );
741
742 if ( ! empty( $item_id ) ) {
743 $item_id = explode( ',', $item_id );
744 }
745
746 $query = array(
747 'form_id' => $form_id,
748 );
749
750 if ( $item_id ) {
751 $query['id'] = $item_id;
752 }
753
754 /**
755 * Allows the query to be changed for fetching the entry ids to include in the export
756 *
757 * $query is the array of options to be filtered. It includes form_id, and maybe id (array of entry ids),
758 * and the search query. This should return an array, but it can be handled as a string as well.
759 */
760 $query = apply_filters( 'frm_csv_where', $query, compact( 'form_id', 'search', 'fid', 'item_id' ) );
761
762 $entry_ids = FrmDb::get_col( $wpdb->prefix . 'frm_items it', $query );
763 unset( $query );
764
765 if ( empty( $entry_ids ) ) {
766 esc_html_e( 'There are no entries for that form.', 'formidable' );
767 } else {
768 FrmCSVExportHelper::generate_csv( compact( 'form', 'entry_ids', 'form_cols' ) );
769 }
770
771 wp_die();
772 }
773
774 /**
775 * Get the fields that should be included in the CSV export
776 *
777 * @since 2.0.19
778 * @since 5.0.16 function went from private to public.
779 *
780 * @param int $form_id
781 * @param object $form
782 *
783 * @return array $csv_fields
784 */
785 public static function get_fields_for_csv_export( $form_id, $form ) {
786 $csv_fields = FrmField::get_all_for_form( $form_id, '', 'include', 'include' );
787 $no_export_fields = FrmField::no_save_fields();
788
789 foreach ( $csv_fields as $k => $f ) {
790 if ( in_array( $f->type, $no_export_fields, true ) ) {
791 unset( $csv_fields[ $k ] );
792 }
793 }
794
795 return apply_filters( 'frm_fields_for_csv_export', $csv_fields, compact( 'form' ) );
796 }
797
798 /**
799 * @param array $mimes
800 *
801 * @return array
802 */
803 public static function allow_mime( $mimes ) {
804 if ( ! isset( $mimes['csv'] ) ) {
805 // allow csv files
806 $mimes['csv'] = 'text/csv';
807 }
808
809 if ( ! isset( $mimes['xml'] ) ) {
810 // allow xml
811 $mimes['xml'] = 'text/xml';
812 }
813
814 return $mimes;
815 }
816 }
817