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

744 lines 21.5 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 );
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 * Disables summary email for multisite (not the main site) if recipient setting isn't changed.
400 *
401 * @since 6.8
402 */
403 private function migrate_to_101() {
404 if ( ! is_multisite() || get_main_site_id() === get_current_blog_id() ) {
405 return;
406 }
407
408 $frm_settings = FrmAppHelper::get_settings();
409 if ( empty( $frm_settings->summary_emails ) || '[admin_email]' !== $frm_settings->summary_emails_recipients ) {
410 // User changed it.
411 return;
412 }
413
414 $frm_settings->summary_emails = 0;
415 $frm_settings->store();
416 }
417
418 /**
419 * Clear frmpro_css transient.
420 *
421 * @since 4.10.02
422 */
423 private function migrate_to_98() {
424 delete_transient( 'frmpro_css' );
425 }
426
427 /**
428 * Move default_blank and clear_on_focus to placeholder.
429 *
430 * @since 4.0
431 */
432 private function migrate_to_97() {
433 $this->migrate_to_placeholder( 'clear_on_focus' );
434 $this->migrate_to_placeholder( 'default_blank' );
435 }
436
437 /**
438 * Move clear_on_focus or default_blank to placeholder.
439 *
440 * @since 4.0
441 */
442 private function migrate_to_placeholder( $type = 'clear_on_focus' ) {
443 $query = array(
444 'field_options like' => '"' . $type . '";s:1:"1";',
445 );
446
447 $fields = FrmDb::get_results( $this->fields, $query, 'id, default_value, field_options, options' );
448
449 foreach ( $fields as $field ) {
450 FrmAppHelper::unserialize_or_decode( $field->field_options );
451 FrmAppHelper::unserialize_or_decode( $field->options );
452 $update_values = FrmXMLHelper::migrate_field_placeholder( $field, $type );
453 if ( empty( $update_values ) ) {
454 continue;
455 }
456
457 FrmField::update( $field->id, $update_values );
458 unset( $field );
459 }
460 }
461
462 /**
463 * Delete unneeded default templates
464 *
465 * @since 3.06
466 */
467 private function migrate_to_90() {
468 $form = FrmForm::getOne( 'contact' );
469 if ( $form && $form->default_template == 1 ) {
470 FrmForm::destroy( 'contact' );
471 }
472 }
473
474 /**
475 * Reverse migration 17 -- Divide by 9
476 *
477 * @since 3.0.05
478 */
479 private function migrate_to_86() {
480
481 $fields = $this->get_fields_with_size();
482
483 foreach ( (array) $fields as $f ) {
484 FrmAppHelper::unserialize_or_decode( $f->field_options );
485 $size = $f->field_options['size'];
486 $this->maybe_convert_migrated_size( $size );
487
488 if ( $size === $f->field_options['size'] ) {
489 continue;
490 }
491
492 $f->field_options['size'] = $size;
493 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
494 unset( $f );
495 }
496
497 // reverse the extra size changes in widgets
498 $widgets = get_option( 'widget_frm_show_form' );
499 if ( empty( $widgets ) ) {
500 return;
501 }
502
503 $this->revert_widget_field_size();
504 }
505
506 private function get_fields_with_size() {
507 $field_types = array(
508 'textarea',
509 'text',
510 'number',
511 'email',
512 'url',
513 'rte',
514 'date',
515 'phone',
516 'password',
517 'image',
518 'tag',
519 'file',
520 );
521
522 $query = array(
523 'type' => $field_types,
524 'field_options like' => 's:4:"size";',
525 'field_options not like' => 's:4:"size";s:0:',
526 );
527
528 return FrmDb::get_results( $this->fields, $query, 'id, field_options' );
529 }
530
531 /**
532 * Reverse the extra size changes in widgets
533 *
534 * @since 3.0.05
535 */
536 private function revert_widget_field_size() {
537 $widgets = get_option( 'widget_frm_show_form' );
538 if ( empty( $widgets ) ) {
539 return;
540 }
541
542 FrmAppHelper::unserialize_or_decode( $widgets );
543 foreach ( $widgets as $k => $widget ) {
544 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
545 continue;
546 }
547
548 $this->maybe_convert_migrated_size( $widgets[ $k ]['size'] );
549 }
550 update_option( 'widget_frm_show_form', $widgets );
551 }
552
553 /**
554 * Divide by 9 to reverse the multiplication
555 *
556 * @since 3.0.05
557 */
558 private function maybe_convert_migrated_size( &$size ) {
559 $has_px_size = ! empty( $size ) && strpos( $size, 'px' );
560 if ( ! $has_px_size ) {
561 return;
562 }
563
564 $int_size = str_replace( 'px', '', $size );
565 if ( ! is_numeric( $int_size ) || (int) $int_size < 900 ) {
566 return;
567 }
568
569 $pixel_conversion = 9;
570
571 $size = round( (int) $int_size / $pixel_conversion );
572 }
573
574 /**
575 * Migrate old styling settings. If sites are using the old
576 * default 400px field width, switch it to 100%
577 *
578 * @since 2.0.4
579 */
580 private function migrate_to_25() {
581 // get the style that was created with the style migration
582 $frm_style = new FrmStyle();
583 $styles = $frm_style->get_all( 'post_date', 'ASC', 1 );
584 if ( empty( $styles ) ) {
585 return;
586 }
587
588 foreach ( $styles as $style ) {
589 if ( $style->post_content['field_width'] === '400px' ) {
590 $style->post_content['field_width'] = '100%';
591 $frm_style->save( (array) $style );
592
593 return;
594 }
595 }
596 }
597
598 /**
599 * Check if the parent_form_id columns exists.
600 * If not, try and add it again
601 *
602 * @since 2.0.2
603 */
604 private function migrate_to_23() {
605 global $wpdb;
606 $exists = $wpdb->get_row( 'SHOW COLUMNS FROM ' . $this->forms . ' LIKE "parent_form_id"' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
607 if ( empty( $exists ) ) {
608 $wpdb->query( 'ALTER TABLE ' . $this->forms . ' ADD parent_form_id int(11) default 0' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
609 }
610 }
611
612 /**
613 * Change field size from character to pixel -- Multiply by 9
614 */
615 private function migrate_to_17() {
616 $fields = $this->get_fields_with_size();
617
618 foreach ( $fields as $f ) {
619 FrmAppHelper::unserialize_or_decode( $f->field_options );
620 if ( empty( $f->field_options['size'] ) || ! is_numeric( $f->field_options['size'] ) ) {
621 continue;
622 }
623
624 $this->convert_character_to_px( $f->field_options['size'] );
625
626 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
627 unset( $f );
628 }
629
630 $this->adjust_widget_size();
631 }
632
633 /**
634 * Change the characters in widgets to pixels
635 */
636 private function adjust_widget_size() {
637 $widgets = get_option( 'widget_frm_show_form' );
638 if ( empty( $widgets ) ) {
639 return;
640 }
641
642 FrmAppHelper::unserialize_or_decode( $widgets );
643 foreach ( $widgets as $k => $widget ) {
644 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
645 continue;
646 }
647 $this->convert_character_to_px( $widgets[ $k ]['size'] );
648 }
649 update_option( 'widget_frm_show_form', $widgets );
650 }
651
652 private function convert_character_to_px( &$size ) {
653 $pixel_conversion = 9;
654
655 $size = round( $pixel_conversion * (int) $size );
656 $size .= 'px';
657 }
658
659 /**
660 * Migrate post and email notification settings into actions
661 */
662 private function migrate_to_16() {
663 $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
664
665 /**
666 * Old email settings format:
667 * email_to: Email or field id
668 * also_email_to: array of fields ids
669 * reply_to: Email, field id, 'custom'
670 * cust_reply_to: string
671 * reply_to_name: field id, 'custom'
672 * cust_reply_to_name: string
673 * plain_text: 0|1
674 * email_message: string or ''
675 * email_subject: string or ''
676 * inc_user_info: 0|1
677 * update_email: 0, 1, 2
678 *
679 * Old autoresponder settings format:
680 * auto_responder: 0|1
681 * ar_email_message: string or ''
682 * ar_email_to: field id
683 * ar_plain_text: 0|1
684 * ar_reply_to_name: string
685 * ar_reply_to: string
686 * ar_email_subject: string
687 * ar_update_email: 0, 1, 2
688 *
689 * New email settings:
690 * post_content: json settings
691 * post_title: form id
692 * post_excerpt: message
693 */
694 foreach ( $forms as $form ) {
695 if ( $form->is_template && $form->default_template ) {
696 // don't migrate the default templates since the email will be added anyway
697 continue;
698 }
699
700 // Format form options
701 $form_options = $form->options;
702 FrmAppHelper::unserialize_or_decode( $form_options );
703
704 // Migrate settings to actions
705 FrmXMLHelper::migrate_form_settings_to_actions( $form_options, $form->id );
706 }
707 }
708
709 private function migrate_to_11() {
710 global $wpdb;
711
712 $forms = FrmDb::get_results( $this->forms, array(), 'id, options' );
713
714 $sending = __( 'Sending', 'formidable' );
715 $img = FrmAppHelper::plugin_url() . '/images/ajax_loader.gif';
716 $old_default_html = <<<DEFAULT_HTML
717 <div class="frm_submit">
718 [if back_button]<input type="submit" value="[back_label]" name="frm_prev_page" formnovalidate="formnovalidate" [back_hook] />[/if back_button]
719 <input type="submit" value="[button_label]" [button_action] />
720 <img class="frm_ajax_loading" src="$img" alt="$sending" style="visibility:hidden;" />
721 </div>
722 DEFAULT_HTML;
723 unset( $sending, $img );
724
725 $new_default_html = FrmFormsHelper::get_default_html( 'submit' );
726 $draft_link = FrmFormsHelper::get_draft_link();
727 foreach ( $forms as $form ) {
728 FrmAppHelper::unserialize_or_decode( $form->options );
729 if ( empty( $form->options['submit_html'] ) ) {
730 continue;
731 }
732
733 if ( $form->options['submit_html'] != $new_default_html && $form->options['submit_html'] == $old_default_html ) {
734 $form->options['submit_html'] = $new_default_html;
735 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
736 } elseif ( ! strpos( $form->options['submit_html'], 'save_draft' ) ) {
737 $form->options['submit_html'] = preg_replace( '~\<\/div\>(?!.*\<\/div\>)~', $draft_link . "\r\n</div>", $form->options['submit_html'] );
738 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
739 }
740 unset( $form );
741 }
742 }
743 }
744