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

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