PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.25
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.25
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 / models / FrmMigrate.php

FrmMigrate.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.25, at classes/models/FrmMigrate.php

762 lines 22.0 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 FrmMigrate {
7 public $fields;
8 public $forms;
9 public $entries;
10 public $entry_metas;
11
12 public function __construct() {
13 global $wpdb;
14 $this->fields = $wpdb->prefix . 'frm_fields';
15 $this->forms = $wpdb->prefix . 'frm_forms';
16 $this->entries = $wpdb->prefix . 'frm_items';
17 $this->entry_metas = $wpdb->prefix . 'frm_item_metas';
18 }
19
20 public function upgrade() {
21 do_action( 'frm_before_install' );
22
23 global $wpdb, $frm_vars;
24
25 $frm_vars['doing_upgrade'] = true;
26
27 $needs_upgrade = FrmAppController::compare_for_update(
28 array(
29 'option' => 'frm_db_version',
30 'new_db_version' => FrmAppHelper::$db_version,
31 'new_plugin_version' => FrmAppHelper::plugin_version(),
32 )
33 );
34
35 if ( $needs_upgrade ) {
36 // update rewrite rules for views and other custom post types
37 flush_rewrite_rules();
38
39 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
40
41 $old_db_version = get_option( 'frm_db_version' );
42
43 $this->create_tables();
44 $this->migrate_data( $old_db_version );
45 $this->check_that_tables_exist();
46
47 // SAVE DB VERSION.
48 update_option( 'frm_db_version', FrmAppHelper::plugin_version() . '-' . FrmAppHelper::$db_version );
49
50 if ( ! $old_db_version ) {
51 $this->maybe_create_contact_form();
52
53 if ( false === get_option( 'frm_first_activation' ) ) {
54 update_option( 'frm_first_activation', time(), false );
55 }
56
57 $this->update_settings_for_new_install();
58 }
59 }//end if
60
61 do_action( 'frm_after_install' );
62
63 $frm_vars['doing_upgrade'] = false;
64
65 FrmAppHelper::save_combined_js();
66
67 // update the styling settings
68 if ( function_exists( 'get_filesystem_method' ) ) {
69 $frm_style = new FrmStyle();
70 $frm_style->update( 'default' );
71 }
72 }
73
74 /**
75 * Updates some settings for new installs.
76 *
77 * @since 6.23
78 */
79 private function update_settings_for_new_install() {
80 $settings = FrmAppHelper::get_settings();
81
82 $settings->denylist_check = 1;
83 $settings->store();
84 }
85
86 /**
87 * If we fail to create the database tables, add an inbox notice.
88 * This informs the user that they need to correct the issue and try again.
89 *
90 * @since 6.19
91 *
92 * @return void
93 */
94 private function check_that_tables_exist() {
95 // Check the DB that the table $this->forms exists.
96 global $wpdb;
97 $exists = $wpdb->get_results( $wpdb->prepare( 'SHOW TABLES LIKE %s', $this->forms ) );
98
99 if ( $exists ) {
100 $inbox = new FrmInbox();
101 $inbox->dismiss( 'failed-to-create-tables' );
102 return;
103 }
104
105 $message = array(
106 'key' => 'failed-to-create-tables',
107 'subject' => 'Something went wrong setting up the database',
108 'message' => 'For steps to continue, see our <a href="https://formidableforms.com/knowledgebase/install-formidable-forms/#kb-missing-database-tables">documentation</a>. If you need assistance, we recommend that you reach out to your hosting provider. Then <a href="' . esc_url( admin_url( 'admin.php?page=formidable&frm_add_tables=1' ) ) . '">click here</a> to try again.',
109 'cta' => '<a href="https://formidableforms.com/knowledgebase/install-formidable-forms/#kb-missing-database-tables">Learn More</a>',
110 'type' => 'error',
111 );
112
113 $inbox = new FrmInbox();
114 $inbox->add_message( $message );
115 }
116
117 /**
118 * @return string
119 */
120 public function collation() {
121 global $wpdb;
122 if ( ! $wpdb->has_cap( 'collation' ) ) {
123 return '';
124 }
125
126 return $wpdb->get_charset_collate();
127 }
128
129 private function create_tables() {
130 $charset_collate = $this->collation();
131 $sql = array();
132
133 /* Create/Upgrade Fields Table */
134 $sql[] = 'CREATE TABLE ' . $this->fields . ' (
135 id BIGINT(20) NOT NULL auto_increment,
136 field_key varchar(100) default NULL,
137 name text default NULL,
138 description longtext default NULL,
139 type text default NULL,
140 default_value longtext default NULL,
141 options longtext default NULL,
142 field_order int(11) default 0,
143 required int(1) default NULL,
144 field_options longtext default NULL,
145 form_id int(11) default NULL,
146 created_at datetime NOT NULL,
147 PRIMARY KEY (id),
148 KEY form_id (form_id),
149 UNIQUE KEY field_key (field_key)
150 )';
151
152 /* Create/Upgrade Forms Table */
153 $sql[] = 'CREATE TABLE ' . $this->forms . ' (
154 id int(11) NOT NULL auto_increment,
155 form_key varchar(100) default NULL,
156 name varchar(255) default NULL,
157 description text default NULL,
158 parent_form_id int(11) default 0,
159 logged_in tinyint(1) default NULL,
160 editable tinyint(1) default NULL,
161 is_template tinyint(1) default 0,
162 default_template tinyint(1) default 0,
163 status varchar(255) default NULL,
164 options longtext default NULL,
165 created_at datetime NOT NULL,
166 PRIMARY KEY (id),
167 UNIQUE KEY form_key (form_key)
168 )';
169
170 /* Create/Upgrade Items Table */
171 $sql[] = 'CREATE TABLE ' . $this->entries . ' (
172 id BIGINT(20) NOT NULL auto_increment,
173 item_key varchar(100) default NULL,
174 name varchar(255) default NULL,
175 description text default NULL,
176 ip text default NULL,
177 form_id BIGINT(20) default NULL,
178 post_id BIGINT(20) default NULL,
179 user_id BIGINT(20) default NULL,
180 parent_item_id BIGINT(20) default 0,
181 is_draft tinyint(1) default 0,
182 updated_by BIGINT(20) default NULL,
183 created_at datetime NOT NULL,
184 updated_at datetime NOT NULL,
185 PRIMARY KEY (id),
186 KEY form_id (form_id),
187 KEY post_id (post_id),
188 KEY user_id (user_id),
189 KEY parent_item_id (parent_item_id),
190 UNIQUE KEY item_key (item_key)
191 )';
192
193 /* Create/Upgrade Meta Table */
194 $sql[] = 'CREATE TABLE ' . $this->entry_metas . ' (
195 id BIGINT(20) NOT NULL auto_increment,
196 meta_value longtext default NULL,
197 field_id BIGINT(20) NOT NULL,
198 item_id BIGINT(20) NOT NULL,
199 created_at datetime NOT NULL,
200 PRIMARY KEY (id),
201 KEY field_id (field_id),
202 KEY item_id (item_id)
203 )';
204
205 foreach ( $sql as $q ) {
206 if ( function_exists( 'dbDelta' ) ) {
207 dbDelta( $q . $charset_collate . ';' );
208 } else {
209 global $wpdb;
210 $wpdb->query( $q . $charset_collate ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
211 }
212 unset( $q );
213 }
214
215 $this->add_composite_indexes_for_entries();
216 }
217
218 /**
219 * These indexes help optimize database queries for entries.
220 *
221 * @since 6.6
222 * @since 6.16.3 idx_form_id_is_draft was also added to frm_items.
223 * @since 6.17 idx_form_id_type was also added to frm_fields.
224 *
225 * @return void
226 */
227 private function add_composite_indexes_for_entries() {
228 global $wpdb;
229
230 $table_name = "{$wpdb->prefix}frm_items";
231 $index_name = 'idx_is_draft_created_at';
232
233 if ( ! self::index_exists( $table_name, $index_name ) ) {
234 $wpdb->query( "CREATE INDEX idx_is_draft_created_at ON `{$wpdb->prefix}frm_items` (is_draft, created_at)" );
235 }
236
237 $table_name = "{$wpdb->prefix}frm_item_metas";
238 $index_name = 'idx_field_id_item_id';
239
240 if ( ! self::index_exists( $table_name, $index_name ) ) {
241 $wpdb->query( "CREATE INDEX idx_field_id_item_id ON `{$wpdb->prefix}frm_item_metas` (field_id, item_id)" );
242 }
243
244 $table_name = "{$wpdb->prefix}frm_items";
245 $index_name = 'idx_form_id_is_draft';
246
247 if ( ! self::index_exists( $table_name, $index_name ) ) {
248 $wpdb->query( "CREATE INDEX idx_form_id_is_draft ON `{$wpdb->prefix}frm_items` (form_id, is_draft)" );
249 }
250
251 $table_name = "{$wpdb->prefix}frm_fields";
252 $index_name = 'idx_form_id_type';
253
254 if ( ! self::index_exists( $table_name, $index_name ) ) {
255 $wpdb->query( "CREATE INDEX idx_form_id_type ON `{$wpdb->prefix}frm_fields` (form_id, type(30))" );
256 }
257 }
258
259 /**
260 * Check that an index exists in a database table before trying to add it (which results in an error).
261 *
262 * @since 6.6
263 *
264 * @param string $table_name
265 * @param string $index_name
266 * @return bool
267 */
268 private static function index_exists( $table_name, $index_name ) {
269 global $wpdb;
270 $row = $wpdb->get_row(
271 $wpdb->prepare(
272 'SELECT 1 FROM information_schema.statistics
273 WHERE table_schema = database()
274 AND table_name = %s
275 AND index_name = %s
276 LIMIT 1',
277 array( $table_name, $index_name )
278 )
279 );
280 return (bool) $row;
281 }
282
283 private function maybe_create_contact_form() {
284 $form_exists = FrmForm::get_id_by_key( 'contact-form' );
285 if ( ! $form_exists ) {
286 $this->add_default_template();
287 }
288 }
289
290 /**
291 * Create the default contact form
292 *
293 * @since 3.06
294 */
295 private function add_default_template() {
296 if ( FrmXMLHelper::check_if_libxml_disable_entity_loader_exists() ) {
297 // XML import is not enabled on your server.
298 return;
299 }
300
301 $set_err = libxml_use_internal_errors( true );
302 $loader = FrmXMLHelper::maybe_libxml_disable_entity_loader( true );
303
304 $file = FrmAppHelper::plugin_path() . '/classes/views/xml/default-templates.xml';
305 FrmXMLHelper::import_xml( $file );
306
307 libxml_use_internal_errors( $set_err );
308 FrmXMLHelper::maybe_libxml_disable_entity_loader( $loader );
309 }
310
311 /**
312 * @param int|string $old_db_version
313 */
314 private function migrate_data( $old_db_version ) {
315 if ( ! $old_db_version ) {
316 $old_db_version = get_option( 'frm_db_version' );
317 }
318 if ( strpos( $old_db_version, '-' ) ) {
319 $last_upgrade = explode( '-', $old_db_version );
320 $old_db_version = (int) $last_upgrade[1];
321 }
322
323 if ( ! is_numeric( $old_db_version ) ) {
324 // bail if we don't know the previous version
325 return;
326 }
327
328 $migrations = array( 16, 11, 16, 17, 23, 25, 86, 90, 97, 98, 101, 104 );
329 foreach ( $migrations as $migration ) {
330 if ( FrmAppHelper::$db_version >= $migration && $old_db_version < $migration ) {
331 $function_name = 'migrate_to_' . $migration;
332 $this->$function_name();
333 }
334 }
335 }
336
337 public function uninstall() {
338 if ( ! current_user_can( 'administrator' ) ) {
339 $frm_settings = FrmAppHelper::get_settings();
340 wp_die( esc_html( $frm_settings->admin_permission ) );
341 }
342
343 global $wpdb, $wp_roles;
344
345 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->fields ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
346 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->forms ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
347 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entries ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
348 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entry_metas ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
349
350 delete_option( 'frm_options' );
351 delete_option( 'frm_db_version' );
352 delete_option( 'frm_install_running' );
353 delete_option( 'frm_lite_settings_upgrade' );
354 delete_option( 'frm-usage-uuid' );
355 delete_option( 'frm_inbox' );
356 delete_option( 'frmpro_css' );
357 delete_option( FrmOnboardingWizardController::REDIRECT_STATUS_OPTION );
358 delete_option( FrmEmailSummaryHelper::$option_name );
359
360 // Delete roles.
361 $frm_roles = FrmAppHelper::frm_capabilities();
362 $roles = get_editable_roles();
363 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
364 foreach ( $roles as $role => $details ) {
365 $wp_roles->remove_cap( $role, $frm_role );
366 unset( $role, $details );
367 }
368 unset( $frm_role, $frm_role_description );
369 }
370 unset( $roles, $frm_roles );
371
372 // delete actions, views, and styles
373
374 // prevent the post deletion from triggering entries to be deleted
375 remove_action( 'before_delete_post', 'FrmProDisplaysController::before_delete_post' );
376 remove_action( 'deleted_post', 'FrmProEntriesController::delete_entry' );
377
378 $post_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT ID FROM ' . $wpdb->posts . ' WHERE post_type in (%s, %s, %s)', FrmFormActionsController::$action_post_type, FrmStylesController::$post_type, 'frm_display' ) );
379 foreach ( $post_ids as $post_id ) {
380 // Delete's each post.
381 wp_delete_post( $post_id, true );
382 }
383 unset( $post_ids );
384
385 // delete transients
386 delete_transient( 'frmpro_css' );
387 delete_transient( 'frm_options' );
388 delete_transient( 'frmpro_options' );
389 delete_transient( FrmOnboardingWizardController::TRANSIENT_NAME );
390
391 $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE %s OR option_name LIKE %s', '_transient_timeout_frm_form_fields_%', '_transient_frm_form_fields_%' ) );
392
393 do_action( 'frm_after_uninstall' );
394
395 return true;
396 }
397
398 /**
399 * In older versions of Lite, it's possible we've saved the wrong location ID.
400 * So force it to get valid values again.
401 *
402 * @since 6.25
403 *
404 * @return void
405 */
406 private function migrate_to_104() {
407 if ( FrmSquareLiteConnectHelper::get_merchant_id( 'test' ) ) {
408 FrmSquareLiteConnectHelper::get_location_id( true, 'test' );
409 }
410
411 if ( FrmSquareLiteConnectHelper::get_merchant_id( 'live' ) ) {
412 FrmSquareLiteConnectHelper::get_location_id( true, 'live' );
413 }
414 }
415
416 /**
417 * Disables summary email for multisite (not the main site) if recipient setting isn't changed.
418 *
419 * @since 6.8
420 */
421 private function migrate_to_101() {
422 if ( ! is_multisite() || get_main_site_id() === get_current_blog_id() ) {
423 return;
424 }
425
426 $frm_settings = FrmAppHelper::get_settings();
427 if ( empty( $frm_settings->summary_emails ) || '[admin_email]' !== $frm_settings->summary_emails_recipients ) {
428 // User changed it.
429 return;
430 }
431
432 $frm_settings->summary_emails = 0;
433 $frm_settings->store();
434 }
435
436 /**
437 * Clear frmpro_css transient.
438 *
439 * @since 4.10.02
440 */
441 private function migrate_to_98() {
442 delete_transient( 'frmpro_css' );
443 }
444
445 /**
446 * Move default_blank and clear_on_focus to placeholder.
447 *
448 * @since 4.0
449 */
450 private function migrate_to_97() {
451 $this->migrate_to_placeholder( 'clear_on_focus' );
452 $this->migrate_to_placeholder( 'default_blank' );
453 }
454
455 /**
456 * Move clear_on_focus or default_blank to placeholder.
457 *
458 * @since 4.0
459 */
460 private function migrate_to_placeholder( $type = 'clear_on_focus' ) {
461 $query = array(
462 'field_options like' => '"' . $type . '";s:1:"1";',
463 );
464
465 $fields = FrmDb::get_results( $this->fields, $query, 'id, default_value, field_options, options' );
466
467 foreach ( $fields as $field ) {
468 FrmAppHelper::unserialize_or_decode( $field->field_options );
469 FrmAppHelper::unserialize_or_decode( $field->options );
470 $update_values = FrmXMLHelper::migrate_field_placeholder( $field, $type );
471 if ( empty( $update_values ) ) {
472 continue;
473 }
474
475 FrmField::update( $field->id, $update_values );
476 unset( $field );
477 }
478 }
479
480 /**
481 * Delete unneeded default templates
482 *
483 * @since 3.06
484 */
485 private function migrate_to_90() {
486 $form = FrmForm::getOne( 'contact' );
487 if ( $form && $form->default_template == 1 ) {
488 FrmForm::destroy( 'contact' );
489 }
490 }
491
492 /**
493 * Reverse migration 17 -- Divide by 9
494 *
495 * @since 3.0.05
496 */
497 private function migrate_to_86() {
498
499 $fields = $this->get_fields_with_size();
500
501 foreach ( (array) $fields as $f ) {
502 FrmAppHelper::unserialize_or_decode( $f->field_options );
503 $size = $f->field_options['size'];
504 $this->maybe_convert_migrated_size( $size );
505
506 if ( $size === $f->field_options['size'] ) {
507 continue;
508 }
509
510 $f->field_options['size'] = $size;
511 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
512 unset( $f );
513 }
514
515 // reverse the extra size changes in widgets
516 $widgets = get_option( 'widget_frm_show_form' );
517 if ( empty( $widgets ) ) {
518 return;
519 }
520
521 $this->revert_widget_field_size();
522 }
523
524 private function get_fields_with_size() {
525 $field_types = array(
526 'textarea',
527 'text',
528 'number',
529 'email',
530 'url',
531 'rte',
532 'date',
533 'phone',
534 'password',
535 'image',
536 'tag',
537 'file',
538 );
539
540 $query = array(
541 'type' => $field_types,
542 'field_options like' => 's:4:"size";',
543 'field_options not like' => 's:4:"size";s:0:',
544 );
545
546 return FrmDb::get_results( $this->fields, $query, 'id, field_options' );
547 }
548
549 /**
550 * Reverse the extra size changes in widgets
551 *
552 * @since 3.0.05
553 */
554 private function revert_widget_field_size() {
555 $widgets = get_option( 'widget_frm_show_form' );
556 if ( empty( $widgets ) ) {
557 return;
558 }
559
560 FrmAppHelper::unserialize_or_decode( $widgets );
561 foreach ( $widgets as $k => $widget ) {
562 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
563 continue;
564 }
565
566 $this->maybe_convert_migrated_size( $widgets[ $k ]['size'] );
567 }
568 update_option( 'widget_frm_show_form', $widgets );
569 }
570
571 /**
572 * Divide by 9 to reverse the multiplication
573 *
574 * @since 3.0.05
575 */
576 private function maybe_convert_migrated_size( &$size ) {
577 $has_px_size = ! empty( $size ) && strpos( $size, 'px' );
578 if ( ! $has_px_size ) {
579 return;
580 }
581
582 $int_size = str_replace( 'px', '', $size );
583 if ( ! is_numeric( $int_size ) || (int) $int_size < 900 ) {
584 return;
585 }
586
587 $pixel_conversion = 9;
588
589 $size = round( (int) $int_size / $pixel_conversion );
590 }
591
592 /**
593 * Migrate old styling settings. If sites are using the old
594 * default 400px field width, switch it to 100%
595 *
596 * @since 2.0.4
597 */
598 private function migrate_to_25() {
599 // get the style that was created with the style migration
600 $frm_style = new FrmStyle();
601 $styles = $frm_style->get_all( 'post_date', 'ASC', 1 );
602 if ( empty( $styles ) ) {
603 return;
604 }
605
606 foreach ( $styles as $style ) {
607 if ( $style->post_content['field_width'] === '400px' ) {
608 $style->post_content['field_width'] = '100%';
609 $frm_style->save( (array) $style );
610
611 return;
612 }
613 }
614 }
615
616 /**
617 * Check if the parent_form_id columns exists.
618 * If not, try and add it again
619 *
620 * @since 2.0.2
621 */
622 private function migrate_to_23() {
623 global $wpdb;
624 $exists = $wpdb->get_row( 'SHOW COLUMNS FROM ' . $this->forms . ' LIKE "parent_form_id"' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
625 if ( empty( $exists ) ) {
626 $wpdb->query( 'ALTER TABLE ' . $this->forms . ' ADD parent_form_id int(11) default 0' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
627 }
628 }
629
630 /**
631 * Change field size from character to pixel -- Multiply by 9
632 */
633 private function migrate_to_17() {
634 $fields = $this->get_fields_with_size();
635
636 foreach ( $fields as $f ) {
637 FrmAppHelper::unserialize_or_decode( $f->field_options );
638 if ( empty( $f->field_options['size'] ) || ! is_numeric( $f->field_options['size'] ) ) {
639 continue;
640 }
641
642 $this->convert_character_to_px( $f->field_options['size'] );
643
644 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
645 unset( $f );
646 }
647
648 $this->adjust_widget_size();
649 }
650
651 /**
652 * Change the characters in widgets to pixels
653 */
654 private function adjust_widget_size() {
655 $widgets = get_option( 'widget_frm_show_form' );
656 if ( empty( $widgets ) ) {
657 return;
658 }
659
660 FrmAppHelper::unserialize_or_decode( $widgets );
661 foreach ( $widgets as $k => $widget ) {
662 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
663 continue;
664 }
665 $this->convert_character_to_px( $widgets[ $k ]['size'] );
666 }
667 update_option( 'widget_frm_show_form', $widgets );
668 }
669
670 private function convert_character_to_px( &$size ) {
671 $pixel_conversion = 9;
672
673 $size = round( $pixel_conversion * (int) $size );
674 $size .= 'px';
675 }
676
677 /**
678 * Migrate post and email notification settings into actions
679 */
680 private function migrate_to_16() {
681 $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
682
683 /**
684 * Old email settings format:
685 * email_to: Email or field id
686 * also_email_to: array of fields ids
687 * reply_to: Email, field id, 'custom'
688 * cust_reply_to: string
689 * reply_to_name: field id, 'custom'
690 * cust_reply_to_name: string
691 * plain_text: 0|1
692 * email_message: string or ''
693 * email_subject: string or ''
694 * inc_user_info: 0|1
695 * update_email: 0, 1, 2
696 *
697 * Old autoresponder settings format:
698 * auto_responder: 0|1
699 * ar_email_message: string or ''
700 * ar_email_to: field id
701 * ar_plain_text: 0|1
702 * ar_reply_to_name: string
703 * ar_reply_to: string
704 * ar_email_subject: string
705 * ar_update_email: 0, 1, 2
706 *
707 * New email settings:
708 * post_content: json settings
709 * post_title: form id
710 * post_excerpt: message
711 */
712 foreach ( $forms as $form ) {
713 if ( $form->is_template && $form->default_template ) {
714 // don't migrate the default templates since the email will be added anyway
715 continue;
716 }
717
718 // Format form options
719 $form_options = $form->options;
720 FrmAppHelper::unserialize_or_decode( $form_options );
721
722 // Migrate settings to actions
723 FrmXMLHelper::migrate_form_settings_to_actions( $form_options, $form->id );
724 }
725 }
726
727 private function migrate_to_11() {
728 global $wpdb;
729
730 $forms = FrmDb::get_results( $this->forms, array(), 'id, options' );
731
732 $sending = __( 'Sending', 'formidable' );
733 $img = FrmAppHelper::plugin_url() . '/images/ajax_loader.gif';
734 $old_default_html = <<<DEFAULT_HTML
735 <div class="frm_submit">
736 [if back_button]<input type="submit" value="[back_label]" name="frm_prev_page" formnovalidate="formnovalidate" [back_hook] />[/if back_button]
737 <input type="submit" value="[button_label]" [button_action] />
738 <img class="frm_ajax_loading" src="$img" alt="$sending" style="visibility:hidden;" />
739 </div>
740 DEFAULT_HTML;
741 unset( $sending, $img );
742
743 $new_default_html = FrmFormsHelper::get_default_html( 'submit' );
744 $draft_link = FrmFormsHelper::get_draft_link();
745 foreach ( $forms as $form ) {
746 FrmAppHelper::unserialize_or_decode( $form->options );
747 if ( empty( $form->options['submit_html'] ) ) {
748 continue;
749 }
750
751 if ( $form->options['submit_html'] != $new_default_html && $form->options['submit_html'] == $old_default_html ) {
752 $form->options['submit_html'] = $new_default_html;
753 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
754 } elseif ( ! strpos( $form->options['submit_html'], 'save_draft' ) ) {
755 $form->options['submit_html'] = preg_replace( '~\<\/div\>(?!.*\<\/div\>)~', $draft_link . "\r\n</div>", $form->options['submit_html'] );
756 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
757 }
758 unset( $form );
759 }
760 }
761 }
762