PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 3.06.06
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v3.06.06
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/models/FrmFormMigrator.php +75 -270 6.43.06.06 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - die( 'You are not allowed to call this page directly.' );
4 -}
5 2
6 3 abstract class FrmFormMigrator {
7 4
8 5 public $source_active;
@@ -13,12 +10,8 @@
13 10
14 11 public $response = array();
15 12 public $tracking = 'frm_forms_imported';
16 13
17 - protected $fields_map = array();
18 - protected $current_source_form = null;
19 - protected $current_section = array();
20 -
21 14 /**
22 15 * Define required properties.
23 16 */
24 17 public function __construct() {
@@ -25,12 +18,8 @@
25 18 if ( ! is_admin() ) {
26 19 return;
27 20 }
28 21
29 - if ( ! function_exists( 'is_plugin_active' ) ) {
30 - require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
31 - }
32 -
33 22 $this->source_active = is_plugin_active( $this->path );
34 23 if ( ! $this->source_active ) {
35 24 // if source plugin is not installed, do nothing
36 25 return;
@@ -44,9 +33,10 @@
44 33 );
45 34 }
46 35
47 36 private function maybe_add_to_import_page() {
48 - add_action( 'frm_import_settings', array( $this, 'import_page' ) );
37 + $menu_name = sanitize_title( FrmAppHelper::get_menu_name() );
38 + add_action( $menu_name . '_page_formidable-import', array( $this, 'import_page' ), 1 );
49 39 add_action( 'wp_ajax_frm_import_' . $this->slug, array( $this, 'import_forms' ) );
50 40 }
51 41
52 42 public function import_page() {
@@ -51,55 +41,46 @@
51 41
52 42 public function import_page() {
53 43 ?>
54 44 <div class="wrap">
55 - <h2 class="frm-h2"><?php echo esc_html( $this->name ); ?> Importer</h2>
56 - <p class="howto">Import forms and settings automatically from <?php echo esc_html( $this->name ); ?>.</p>
57 - <div id="welcome-panel">
58 - <div style="margin-bottom:10px;">
45 + <div class="welcome-panel" id="welcome-panel">
46 + <h2><?php echo esc_html( $this->name ); ?> Importer</h2>
47 + <div class="welcome-panel-content" style="text-align:center;margin-bottom:10px;">
59 48 <p class="about-description">
49 + Import forms and settings automatically from <?php echo esc_html( $this->name ); ?>. <br/>
60 50 Select the forms to import.
61 51 </p>
62 - <form class="frm_form_importer" method="post"
63 - action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>">
52 + <form id="frm_form_importer" method="post" action="<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>">
64 53 <?php wp_nonce_field( 'nonce', 'frm_ajax' ); ?>
65 54 <input type="hidden" name="slug" value="<?php echo esc_attr( $this->slug ); ?>" />
66 55 <input type="hidden" name="action" value="frm_import_<?php echo esc_attr( $this->slug ); ?>" />
67 - <div style="max-width:400px;text-align:left;">
68 - <?php
69 - if ( empty( $this->get_forms() ) ) {
70 - esc_html_e( 'No Forms Found.', 'formidable' );
71 - }
72 - ?>
56 + <div style="margin:10px auto;max-width:400px;text-align:left;">
73 57 <?php foreach ( $this->get_forms() as $form_id => $name ) { ?>
74 58 <p>
75 59 <label>
76 - <input type="checkbox" name="form_id[]"
77 - value="<?php echo esc_attr( $form_id ); ?>" checked="checked" />
60 + <input type="checkbox" name="form_id[]" value="<?php echo esc_attr( $form_id ); ?>" checked="checked" />
78 61 <?php
79 62 echo esc_html( $name );
80 63 $new_form_id = $this->is_imported( $form_id );
81 64 ?>
82 65 <?php if ( $new_form_id ) { ?>
83 - (<a href="<?php echo esc_url( FrmForm::get_edit_link( $new_form_id ) ); ?>">previously imported</a>)
66 + (<a href="<?php echo esc_url( admin_url( 'admin.php?page=formidable&frm_action=edit&id=' . $new_form_id ) ); ?>">previously imported</a>)
84 67 <?php } ?>
85 68 </label>
86 69 </p>
87 70 <?php } ?>
88 71 </div>
89 - <p class="submit"><button type="submit" class="button button-primary frm-button-primary">Start Import</button></p>
72 + <button type="submit" class="button button-primary button-hero">Start Import</button>
90 73 </form>
91 - <div id="frm-importer-process" class="frm-importer-process frm_hidden">
74 + <div id="frm-importer-process" class="frm_hidden">
92 75
93 76 <p class="process-count">
94 - <span class="frm-wait" aria-hidden="true"></span>
95 - Importing <span class="form-current">1</span> of <span class="form-total">0</span> forms
96 - from <?php echo esc_html( $this->name ); ?>.
77 + <i class="fa fa-spinner fa-spin" aria-hidden="true"></i>
78 + Importing <span class="form-current">1</span> of <span class="form-total">0</span> forms from <?php echo esc_html( $this->name ); ?>.
97 79 </p>
98 80
99 81 <p class="process-completed" class="frm_hidden">
100 - The import process has finished! We have successfully imported
101 - <span class="forms-completed"></span> forms. You can review the results below.
82 + The import process has finished! We have successfully imported <span class="forms-completed"></span> forms. You can review the results below.
102 83 </p>
103 84
104 85 <div class="status"></div>
105 86
@@ -142,15 +123,12 @@
142 123 * Import a single form
143 124 */
144 125 protected function import_form( $source_id ) {
145 126
146 - $source_form = $this->get_form( $source_id );
147 - $source_form_name = $this->get_form_name( $source_form );
148 - $source_fields = $this->get_form_fields( $source_form );
149 - $this->maybe_add_end_fields( $source_fields );
127 + $source_form = $this->get_form( $source_id );
128 + $source_form_name = $this->get_form_name( $source_form );
129 + $source_fields = $this->get_form_fields( $source_id );
150 130
151 - $this->current_source_form = $source_form;
152 -
153 131 // If form does not contain fields, bail.
154 132 if ( empty( $source_fields ) ) {
155 133 wp_send_json_success(
156 134 array(
@@ -166,14 +144,9 @@
166 144 $this->prepare_fields( $source_fields, $form );
167 145
168 146 $this->prepare_form( $source_form, $form );
169 147
170 - $response = $this->add_form( $form );
171 -
172 - // reset
173 - $this->current_source_form = null;
174 -
175 - return $response;
148 + return $this->add_form( $form );
176 149 }
177 150
178 151 protected function prepare_new_form( $source_id, $source_form_name ) {
179 152 return array(
@@ -191,11 +164,9 @@
191 164 }
192 165
193 166 protected function prepare_fields( $fields, &$form ) {
194 167 $field_order = 1;
195 -
196 168 foreach ( $fields as $field ) {
197 - $field = (array) $field;
198 169
199 170 $label = $this->get_field_label( $field );
200 171 $type = $this->get_field_type( $field );
201 172
@@ -209,41 +180,17 @@
209 180 $this->response['upgrade_omit'][] = $label;
210 181 continue;
211 182 }
212 183
213 - $new_type = $this->convert_field_type( $type, $field );
214 -
215 - $new_field = FrmFieldsHelper::setup_new_vars( $new_type );
216 - $new_field['name'] = $label;
184 + $new_field = FrmFieldsHelper::setup_new_vars( $this->convert_field_type( $type ) );
185 + $new_field['name'] = $label;
217 186 $new_field['field_order'] = $field_order;
218 - $new_field['original'] = $type;
187 + $new_field['original'] = $type;
219 188
220 189 $this->prepare_field( $field, $new_field );
221 -
222 - $in_section = ! empty( $this->current_section ) && ! in_array( $new_type, $this->fields_with_end() ) && $new_type !== 'break';
223 - if ( $in_section ) {
224 - $new_field['field_options']['in_section'] = $this->current_section['id'];
225 - }
226 -
227 190 $form['fields'][] = $new_field;
228 191
229 - if ( in_array( $new_type, $this->fields_with_end() ) ) {
230 - $this->current_section = $field;
231 - } elseif ( $new_type === 'break' || $new_type === 'end_divider' ) {
232 - $this->current_section = array();
233 - }
234 -
235 - // This may occassionally skip one level/order e.g. after adding a
236 - // list field, as field_order would already be prepared to be used.
237 - $field_order ++;
238 -
239 - if ( isset( $new_field['fields'] ) && is_array( $new_field['fields'] ) && ! empty( $new_field['fields'] ) ) {
240 - // we have (inner) fields to merge
241 -
242 - $form['fields'] = array_merge( $form['fields'], $new_field['fields'] );
243 - // set the new field_order as it would have changed
244 - $field_order = $new_field['current_order'];
245 - }
192 + $field_order++;
246 193 }
247 194 }
248 195
249 196 protected function prepare_field( $field, &$new_field ) {
@@ -249,196 +196,71 @@
249 196 protected function prepare_field( $field, &$new_field ) {
250 197 // customize this function
251 198 }
252 199
253 - /**
254 - * Add any field types that will need an end section field.
255 - *
256 - * @since 4.04.03
257 - */
258 - protected function fields_with_end() {
259 - return array( 'divider' );
200 + protected function convert_field_type( $type ) {
201 + return $type;
260 202 }
261 203
262 204 /**
263 - * @since 4.04.03
264 - */
265 - protected function maybe_add_end_fields( &$fields ) {
266 - $with_end = $this->fields_with_end();
267 - if ( empty( $with_end ) ) {
268 - return;
269 - }
270 -
271 - $open = array();
272 -
273 - $order = 0;
274 - foreach ( $fields as $field ) {
275 - $order ++;
276 - $type = $this->get_field_type( $field );
277 - $new_type = $this->convert_field_type( $type, $field );
278 - if ( ! in_array( $new_type, $with_end ) && $new_type !== 'break' ) {
279 - continue;
280 - }
281 -
282 - if ( ! empty( $open ) ) {
283 - $this->insert_end_section( $fields, $order );
284 - $open = array();
285 - }
286 -
287 - if ( in_array( $new_type, $with_end ) ) {
288 - $open = $field;
289 - }
290 - }
291 -
292 - if ( ! empty( $open ) ) {
293 - $this->insert_end_section( $fields, $order );
294 - }
295 - }
296 -
297 - /**
298 - * @since 4.04.03
299 - */
300 - protected function insert_end_section( &$fields, &$order ) {
301 - $sub = FrmFieldsHelper::setup_new_vars( 'end_divider' );
302 - $sub['name'] = __( 'Section Buttons', 'formidable' );
303 - $subs = array( $sub );
304 - $this->insert_fields_in_array( $subs, $order, 0, $fields );
305 - $order ++;
306 - }
307 -
308 - /**
309 - * Replace the original combo field with a group.
310 - * This switches the name field to individual fields.
205 + * Add the new form to the database and return AJAX data.
311 206 *
312 - * @since 4.04.03
313 - */
314 - protected function insert_fields_in_array( $subs, $start, $remove, &$fields ) {
315 - array_splice( $fields, $start, $remove, $subs );
316 - }
317 -
318 - /**
319 - * @param string $type
320 - * @param array $field
321 - * @param string $use Which field type to prefer to consider $field as.
322 - * This also eases the recursive use of the method,
323 - * particularly the overrides in child classes, as
324 - * there will be no need to rebuild the converter
325 - * array at usage locations.
326 - */
327 - protected function convert_field_type( $type, $field = array(), $use = '' ) {
328 - if ( empty( $field ) ) {
329 - // For reverse compatability.
330 - return $type;
331 - }
332 -
333 - return $use ? $use : $field['type'];
334 - }
335 -
336 - /**
337 - * Add the new form to the database and return AJAX data.å
207 + * @since 1.4.2
338 208 *
339 209 * @param array $form Form to import.
340 210 * @param array $upgrade_omit No field alternative
341 211 */
342 - protected function add_form( $form, $upgrade_omit = array() ) {
212 + private function add_form( $form, $upgrade_omit = array() ) {
343 213
344 214 // Create empty form so we have an ID to work with.
345 - $form_id = $this->create_form( $form );
215 + $form_id = FrmForm::create(
216 + array(
217 + 'name' => $form['name'],
218 + 'description' => $form['description'],
219 + 'options' => $form['options'],
220 + 'form_key' => $form['name'],
221 + 'status' => 'published',
222 + )
223 + );
346 224
347 225 if ( empty( $form_id ) ) {
348 - return $this->form_creation_error_response( $form );
226 + return array(
227 + 'error' => true,
228 + 'name' => sanitize_text_field( $form['settings']['form_title'] ),
229 + 'msg' => esc_html__( 'There was an error while creating a new form.', 'formidable' ),
230 + );
349 231 }
350 232
351 - $this->create_fields( $form_id, $form );
352 -
353 - $this->create_emails( $form, $form_id );
354 -
355 - $this->track_import( $form['import_form_id'], $form_id );
356 -
357 - // Build and send final AJAX response!
358 - return array(
359 - 'name' => $form['name'],
360 - 'id' => $form_id,
361 - 'link' => esc_url_raw( FrmForm::get_edit_link( $form_id ) ),
362 - 'upgrade_omit' => $this->response['upgrade_omit'],
363 - );
364 - }
365 -
366 - /**
367 - * @since 4.04.03
368 - *
369 - * @param array $form parameters for the new form to be created. Only
370 - * the name key is a must. The keys are the column
371 - * names of the forms table in the DB.
372 - *
373 - * @return bool|int The ID of the newly created form or false on failure.
374 - */
375 - protected function create_form( $form ) {
376 - $form['form_key'] = $form['name'];
377 - $form['status'] = 'published';
378 -
379 - return FrmForm::create( $form );
380 - }
381 -
382 - /**
383 - * @since 4.04.03
384 - */
385 - protected function form_creation_error_response( $form ) {
386 - return array(
387 - 'error' => true,
388 - 'name' => sanitize_text_field( $form['name'] ),
389 - 'msg' => esc_html__( 'There was an error while creating a new form.', 'formidable' ),
390 - );
391 - }
392 -
393 - /**
394 - * @since 4.04.03
395 - *
396 - * @param int $form_id
397 - * @param array $form
398 - */
399 - protected function create_fields( $form_id, &$form ) {
400 233 foreach ( $form['fields'] as $key => $new_field ) {
401 - $new_field['form_id'] = $form_id;
234 + $new_field['form_id'] = $form_id;
402 235 $form['fields'][ $key ]['id'] = FrmField::create( $new_field );
403 236 }
404 - }
405 237
406 - /**
407 - * @since 4.04.03
408 - *
409 - * @param array $form
410 - */
411 - protected function create_emails( $form, $form_id ) {
238 + // create emails
412 239 foreach ( $form['actions'] as $action ) {
413 - $this->save_action( $action, $form, $form_id );
240 + $action_control = FrmFormActionsController::get_form_actions( $action['type'] );
241 + unset( $action['type'] );
242 + $new_action = $action_control->prepare_new( $form_id );
243 + foreach ( $action as $key => $value ) {
244 + if ( $key === 'post_title' ) {
245 + $new_action->post_title = $value;
246 + } else {
247 + $new_action->post_content[ $key ] = $this->replace_smart_tags( $value, $form['fields'] );
248 + }
249 + }
250 +
251 + $action_control->save_settings( $new_action );
414 252 }
415 - }
416 253
417 - /**
418 - * @since 4.04.03
419 - *
420 - * @param array $form
421 - */
422 - protected function save_action( $action, $form, $form_id ) {
423 - $action_control = FrmFormActionsController::get_form_actions( $action['type'] );
424 - unset( $action['type'] );
425 - $new_action = $action_control->prepare_new( $form_id );
426 - foreach ( $action as $key => $value ) {
427 - if ( $key === 'post_title' ) {
428 - $new_action->post_title = $value;
429 - } elseif ( $key === 'ID' ) {
430 - $new_action->ID = $value;
431 - } elseif ( $key === 'the_post_title' ) {
432 - $new_action->post_content['post_title'] = $value;
433 - } elseif ( is_string( $value ) ) {
434 - $new_action->post_content[ $key ] = $this->replace_smart_tags( $value, $form['fields'] );
435 - } else {
436 - $new_action->post_content[ $key ] = $value;
437 - }
438 - }
254 + $this->track_import( $form['import_form_id'], $form_id );
439 255
440 - return $action_control->save_settings( $new_action );
256 + // Build and send final AJAX response!
257 + return array(
258 + 'name' => $form['name'],
259 + 'id' => $form_id,
260 + 'link' => esc_url_raw( admin_url( 'admin.php?page=formidable&frm_action=edit&id=' . $form_id ) ),
261 + 'upgrade_omit' => $this->response['upgrade_omit'],
262 + );
441 263 }
442 264
443 265 /**
444 266 * After a form has been successfully imported we track it, so that in the
@@ -447,9 +269,9 @@
447 269 *
448 270 * @param int $source_id Imported plugin form ID
449 271 * @param int $new_form_id Formidable form ID
450 272 */
451 - protected function track_import( $source_id, $new_form_id ) {
273 + private function track_import( $source_id, $new_form_id ) {
452 274
453 275 $imported = $this->get_tracked_import();
454 276
455 277 $imported[ $this->slug ][ $new_form_id ] = $source_id;
@@ -469,20 +291,13 @@
469 291 *
470 292 * @return int the ID of the created form or 0
471 293 */
472 294 private function is_imported( $source_id ) {
473 - $imported = $this->get_tracked_import();
295 + $imported = $this->get_tracked_import();
474 296 $new_form_id = 0;
475 - if ( ! isset( $imported[ $this->slug ] ) || ! in_array( $source_id, $imported[ $this->slug ] ) ) {
476 - return $new_form_id;
297 + if ( isset( $imported[ $this->slug ] ) && in_array( $source_id, $imported[ $this->slug ] ) ) {
298 + $new_form_id = array_search( $source_id, array_reverse( $imported[ $this->slug ], true ) );
477 299 }
478 -
479 - $new_form_id = array_search( $source_id, array_reverse( $imported[ $this->slug ], true ) );
480 - if ( ! empty( $new_form_id ) && empty( FrmForm::get_key_by_id( $new_form_id ) ) ) {
481 - // Allow reimport if the form was deleted.
482 - $new_form_id = 0;
483 - }
484 -
485 300 return $new_form_id;
486 301 }
487 302
488 303 /** Start functions here that should be overridden **/
@@ -495,9 +310,8 @@
495 310 }
496 311
497 312 private function is_unsupported_field( $type ) {
498 313 $fields = $this->unsupported_field_types();
499 -
500 314 return in_array( $type, $fields, true );
501 315 }
502 316
503 317 /**
@@ -508,11 +322,10 @@
508 322 protected function skip_pro_fields() {
509 323 return array();
510 324 }
511 325
512 - protected function should_skip_field( $type ) {
326 + private function should_skip_field( $type ) {
513 327 $skip_pro_fields = $this->skip_pro_fields();
514 -
515 328 return ( ! FrmAppHelper::pro_is_installed() && in_array( $type, $skip_pro_fields, true ) );
516 329 }
517 330
518 331 /**
@@ -518,9 +331,9 @@
518 331 /**
519 332 * Replace 3rd-party form provider tags/shortcodes with our own Tags.
520 333 *
521 334 * @param string $string String to process the smart tag in.
522 - * @param array $fields List of fields for the form.
335 + * @param array $fields List of fields for the form.
523 336 *
524 337 * @return string
525 338 */
526 339 protected function replace_smart_tags( $string, $fields ) {
@@ -541,9 +354,8 @@
541 354 }
542 355
543 356 /**
544 357 * @param object|array $source_form
545 - *
546 358 * @return string
547 359 */
548 360 protected function get_form_name( $source_form ) {
549 361 return __( 'Default Form', 'formidable' );
@@ -549,10 +361,9 @@
549 361 return __( 'Default Form', 'formidable' );
550 362 }
551 363
552 364 /**
553 - * @param object|array $source_form
554 - *
365 + * @param object|array|int $source_form
555 366 * @return array
556 367 */
557 368 protected function get_form_fields( $source_form ) {
558 369 return array();
@@ -558,28 +369,22 @@
558 369 return array();
559 370 }
560 371
561 372 /**
562 - * @param array $field
563 - *
373 + * @param object|array $field
564 374 * @return string
565 375 */
566 376 protected function get_field_type( $field ) {
567 - return $field['type'];
377 + return is_array( $field ) ? $field['type'] : $field->type;
568 378 }
569 379
570 380 /**
571 - * @param array $field
381 + * @param object|array $field
572 382 *
573 383 * @return string
574 384 */
575 385 protected function get_field_label( $field ) {
576 - $label = isset( $field['label'] ) ? $field['label'] : '';
577 - if ( ! empty( $label ) ) {
578 - return $label;
579 - }
580 -
581 - $type = $this->get_field_type( $field );
386 + $type = $this->get_field_type( $field );
582 387 $label = sprintf(
583 388 /* translators: %1$s - field type */
584 389 esc_html__( '%1$s Field', 'formidable' ),
585 390 ucfirst( $type )