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