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

603 lines 17.3 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
46 /***** SAVE DB VERSION *****/
47 update_option( 'frm_db_version', FrmAppHelper::plugin_version() . '-' . FrmAppHelper::$db_version );
48
49 if ( ! $old_db_version ) {
50 $this->maybe_create_contact_form();
51 }
52 }
53
54 do_action( 'frm_after_install' );
55
56 $frm_vars['doing_upgrade'] = false;
57
58 FrmAppHelper::save_combined_js();
59
60 // update the styling settings
61 if ( function_exists( 'get_filesystem_method' ) ) {
62 $frm_style = new FrmStyle();
63 $frm_style->update( 'default' );
64 }
65 }
66
67 public function collation() {
68 global $wpdb;
69 if ( ! $wpdb->has_cap( 'collation' ) ) {
70 return '';
71 }
72
73 return $wpdb->get_charset_collate();
74 }
75
76 private function create_tables() {
77 $charset_collate = $this->collation();
78 $sql = array();
79
80 /* Create/Upgrade Fields Table */
81 $sql[] = 'CREATE TABLE ' . $this->fields . ' (
82 id BIGINT(20) NOT NULL auto_increment,
83 field_key varchar(100) default NULL,
84 name text default NULL,
85 description longtext default NULL,
86 type text default NULL,
87 default_value longtext default NULL,
88 options longtext default NULL,
89 field_order int(11) default 0,
90 required int(1) default NULL,
91 field_options longtext default NULL,
92 form_id int(11) default NULL,
93 created_at datetime NOT NULL,
94 PRIMARY KEY (id),
95 KEY form_id (form_id),
96 UNIQUE KEY field_key (field_key)
97 )';
98
99 /* Create/Upgrade Forms Table */
100 $sql[] = 'CREATE TABLE ' . $this->forms . ' (
101 id int(11) NOT NULL auto_increment,
102 form_key varchar(100) default NULL,
103 name varchar(255) default NULL,
104 description text default NULL,
105 parent_form_id int(11) default 0,
106 logged_in tinyint(1) default NULL,
107 editable tinyint(1) default NULL,
108 is_template tinyint(1) default 0,
109 default_template tinyint(1) default 0,
110 status varchar(255) default NULL,
111 options longtext default NULL,
112 created_at datetime NOT NULL,
113 PRIMARY KEY (id),
114 UNIQUE KEY form_key (form_key)
115 )';
116
117 /* Create/Upgrade Items Table */
118 $sql[] = 'CREATE TABLE ' . $this->entries . ' (
119 id BIGINT(20) NOT NULL auto_increment,
120 item_key varchar(100) default NULL,
121 name varchar(255) default NULL,
122 description text default NULL,
123 ip text default NULL,
124 form_id BIGINT(20) default NULL,
125 post_id BIGINT(20) default NULL,
126 user_id BIGINT(20) default NULL,
127 parent_item_id BIGINT(20) default 0,
128 is_draft tinyint(1) default 0,
129 updated_by BIGINT(20) default NULL,
130 created_at datetime NOT NULL,
131 updated_at datetime NOT NULL,
132 PRIMARY KEY (id),
133 KEY form_id (form_id),
134 KEY post_id (post_id),
135 KEY user_id (user_id),
136 KEY parent_item_id (parent_item_id),
137 UNIQUE KEY item_key (item_key)
138 )';
139
140 /* Create/Upgrade Meta Table */
141 $sql[] = 'CREATE TABLE ' . $this->entry_metas . ' (
142 id BIGINT(20) NOT NULL auto_increment,
143 meta_value longtext default NULL,
144 field_id BIGINT(20) NOT NULL,
145 item_id BIGINT(20) NOT NULL,
146 created_at datetime NOT NULL,
147 PRIMARY KEY (id),
148 KEY field_id (field_id),
149 KEY item_id (item_id)
150 )';
151
152 foreach ( $sql as $q ) {
153 if ( function_exists( 'dbDelta' ) ) {
154 dbDelta( $q . $charset_collate . ';' );
155 } else {
156 global $wpdb;
157 $wpdb->query( $q . $charset_collate ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
158 }
159 unset( $q );
160 }
161 }
162
163 private function maybe_create_contact_form() {
164 $form_exists = FrmForm::get_id_by_key( 'contact-form' );
165 if ( ! $form_exists ) {
166 $this->add_default_template();
167 }
168 }
169
170 /**
171 * Create the default contact form
172 *
173 * @since 3.06
174 */
175 private function add_default_template() {
176 if ( FrmXMLHelper::check_if_libxml_disable_entity_loader_exists() ) {
177 // XML import is not enabled on your server.
178 return;
179 }
180
181 $set_err = libxml_use_internal_errors( true );
182 $loader = FrmXMLHelper::maybe_libxml_disable_entity_loader( true );
183
184 $file = FrmAppHelper::plugin_path() . '/classes/views/xml/default-templates.xml';
185 FrmXMLHelper::import_xml( $file );
186
187 libxml_use_internal_errors( $set_err );
188 FrmXMLHelper::maybe_libxml_disable_entity_loader( $loader );
189 }
190
191 /**
192 * @param int|string $old_db_version
193 */
194 private function migrate_data( $old_db_version ) {
195 if ( ! $old_db_version ) {
196 $old_db_version = get_option( 'frm_db_version' );
197 }
198 if ( strpos( $old_db_version, '-' ) ) {
199 $last_upgrade = explode( '-', $old_db_version );
200 $old_db_version = (int) $last_upgrade[1];
201 }
202
203 if ( ! is_numeric( $old_db_version ) ) {
204 // bail if we don't know the previous version
205 return;
206 }
207
208 $migrations = array( 16, 11, 16, 17, 23, 25, 86, 90, 97, 98 );
209 foreach ( $migrations as $migration ) {
210 if ( FrmAppHelper::$db_version >= $migration && $old_db_version < $migration ) {
211 $function_name = 'migrate_to_' . $migration;
212 $this->$function_name();
213 }
214 }
215 }
216
217 public function uninstall() {
218 if ( ! current_user_can( 'administrator' ) ) {
219 $frm_settings = FrmAppHelper::get_settings();
220 wp_die( esc_html( $frm_settings->admin_permission ) );
221 }
222
223 global $wpdb, $wp_roles;
224
225 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->fields ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
226 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->forms ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
227 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entries ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
228 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entry_metas ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
229
230 delete_option( 'frm_options' );
231 delete_option( 'frm_db_version' );
232 delete_option( 'frm_install_running' );
233 delete_option( 'frm_lite_settings_upgrade' );
234 delete_option( 'frm-usage-uuid' );
235 delete_option( 'frm_inbox' );
236 delete_option( 'frmpro_css' );
237 delete_option( 'frm_welcome_redirect' );
238
239 // Delete roles.
240 $frm_roles = FrmAppHelper::frm_capabilities();
241 $roles = get_editable_roles();
242 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
243 foreach ( $roles as $role => $details ) {
244 $wp_roles->remove_cap( $role, $frm_role );
245 unset( $role, $details );
246 }
247 unset( $frm_role, $frm_role_description );
248 }
249 unset( $roles, $frm_roles );
250
251 // delete actions, views, and styles
252
253 // prevent the post deletion from triggering entries to be deleted
254 remove_action( 'before_delete_post', 'FrmProDisplaysController::before_delete_post' );
255 remove_action( 'deleted_post', 'FrmProEntriesController::delete_entry' );
256
257 $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' ) );
258 foreach ( $post_ids as $post_id ) {
259 // Delete's each post.
260 wp_delete_post( $post_id, true );
261 }
262 unset( $post_ids );
263
264 // delete transients
265 delete_transient( 'frmpro_css' );
266 delete_transient( 'frm_options' );
267 delete_transient( 'frmpro_options' );
268 delete_transient( 'frm_activation_redirect' );
269
270 $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_%' ) );
271
272 do_action( 'frm_after_uninstall' );
273
274 return true;
275 }
276
277 /**
278 * Clear frmpro_css transient.
279 *
280 * @since 4.10.02
281 */
282 private function migrate_to_98() {
283 delete_transient( 'frmpro_css' );
284 }
285
286 /**
287 * Move default_blank and clear_on_focus to placeholder.
288 *
289 * @since 4.0
290 */
291 private function migrate_to_97() {
292 $this->migrate_to_placeholder( 'clear_on_focus' );
293 $this->migrate_to_placeholder( 'default_blank' );
294 }
295
296 /**
297 * Move clear_on_focus or default_blank to placeholder.
298 *
299 * @since 4.0
300 */
301 private function migrate_to_placeholder( $type = 'clear_on_focus' ) {
302 $query = array(
303 'field_options like' => '"' . $type . '";s:1:"1";',
304 );
305
306 $fields = FrmDb::get_results( $this->fields, $query, 'id, default_value, field_options, options' );
307
308 foreach ( $fields as $field ) {
309 FrmAppHelper::unserialize_or_decode( $field->field_options );
310 FrmAppHelper::unserialize_or_decode( $field->options );
311 $update_values = FrmXMLHelper::migrate_field_placeholder( $field, $type );
312 if ( empty( $update_values ) ) {
313 continue;
314 }
315
316 FrmField::update( $field->id, $update_values );
317 unset( $field );
318 }
319 }
320
321 /**
322 * Delete uneeded default templates
323 *
324 * @since 3.06
325 */
326 private function migrate_to_90() {
327 $form = FrmForm::getOne( 'contact' );
328 if ( $form && $form->default_template == 1 ) {
329 FrmForm::destroy( 'contact' );
330 }
331 }
332
333 /**
334 * Reverse migration 17 -- Divide by 9
335 *
336 * @since 3.0.05
337 */
338 private function migrate_to_86() {
339
340 $fields = $this->get_fields_with_size();
341
342 foreach ( (array) $fields as $f ) {
343 FrmAppHelper::unserialize_or_decode( $f->field_options );
344 $size = $f->field_options['size'];
345 $this->maybe_convert_migrated_size( $size );
346
347 if ( $size === $f->field_options['size'] ) {
348 continue;
349 }
350
351 $f->field_options['size'] = $size;
352 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
353 unset( $f );
354 }
355
356 // reverse the extra size changes in widgets
357 $widgets = get_option( 'widget_frm_show_form' );
358 if ( empty( $widgets ) ) {
359 return;
360 }
361
362 $this->revert_widget_field_size();
363 }
364
365 private function get_fields_with_size() {
366 $field_types = array(
367 'textarea',
368 'text',
369 'number',
370 'email',
371 'url',
372 'rte',
373 'date',
374 'phone',
375 'password',
376 'image',
377 'tag',
378 'file',
379 );
380
381 $query = array(
382 'type' => $field_types,
383 'field_options like' => 's:4:"size";',
384 'field_options not like' => 's:4:"size";s:0:',
385 );
386
387 return FrmDb::get_results( $this->fields, $query, 'id, field_options' );
388 }
389
390 /**
391 * Reverse the extra size changes in widgets
392 *
393 * @since 3.0.05
394 */
395 private function revert_widget_field_size() {
396 $widgets = get_option( 'widget_frm_show_form' );
397 if ( empty( $widgets ) ) {
398 return;
399 }
400
401 FrmAppHelper::unserialize_or_decode( $widgets );
402 foreach ( $widgets as $k => $widget ) {
403 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
404 continue;
405 }
406
407 $this->maybe_convert_migrated_size( $widgets[ $k ]['size'] );
408 }
409 update_option( 'widget_frm_show_form', $widgets );
410 }
411
412 /**
413 * Divide by 9 to reverse the multiplication
414 *
415 * @since 3.0.05
416 */
417 private function maybe_convert_migrated_size( &$size ) {
418 $has_px_size = ! empty( $size ) && strpos( $size, 'px' );
419 if ( ! $has_px_size ) {
420 return;
421 }
422
423 $int_size = str_replace( 'px', '', $size );
424 if ( ! is_numeric( $int_size ) || (int) $int_size < 900 ) {
425 return;
426 }
427
428 $pixel_conversion = 9;
429
430 $size = round( (int) $int_size / $pixel_conversion );
431 }
432
433 /**
434 * Migrate old styling settings. If sites are using the old
435 * default 400px field width, switch it to 100%
436 *
437 * @since 2.0.4
438 */
439 private function migrate_to_25() {
440 // get the style that was created with the style migration
441 $frm_style = new FrmStyle();
442 $styles = $frm_style->get_all( 'post_date', 'ASC', 1 );
443 if ( empty( $styles ) ) {
444 return;
445 }
446
447 foreach ( $styles as $style ) {
448 if ( $style->post_content['field_width'] == '400px' ) {
449 $style->post_content['field_width'] = '100%';
450 $frm_style->save( (array) $style );
451
452 return;
453 }
454 }
455 }
456
457 /**
458 * Check if the parent_form_id columns exists.
459 * If not, try and add it again
460 *
461 * @since 2.0.2
462 */
463 private function migrate_to_23() {
464 global $wpdb;
465 $exists = $wpdb->get_row( 'SHOW COLUMNS FROM ' . $this->forms . ' LIKE "parent_form_id"' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
466 if ( empty( $exists ) ) {
467 $wpdb->query( 'ALTER TABLE ' . $this->forms . ' ADD parent_form_id int(11) default 0' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
468 }
469 }
470
471 /**
472 * Change field size from character to pixel -- Multiply by 9
473 */
474 private function migrate_to_17() {
475 $fields = $this->get_fields_with_size();
476
477 foreach ( $fields as $f ) {
478 FrmAppHelper::unserialize_or_decode( $f->field_options );
479 if ( empty( $f->field_options['size'] ) || ! is_numeric( $f->field_options['size'] ) ) {
480 continue;
481 }
482
483 $this->convert_character_to_px( $f->field_options['size'] );
484
485 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
486 unset( $f );
487 }
488
489 $this->adjust_widget_size();
490 }
491
492 /**
493 * Change the characters in widgets to pixels
494 */
495 private function adjust_widget_size() {
496 $widgets = get_option( 'widget_frm_show_form' );
497 if ( empty( $widgets ) ) {
498 return;
499 }
500
501 FrmAppHelper::unserialize_or_decode( $widgets );
502 foreach ( $widgets as $k => $widget ) {
503 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
504 continue;
505 }
506 $this->convert_character_to_px( $widgets[ $k ]['size'] );
507 }
508 update_option( 'widget_frm_show_form', $widgets );
509 }
510
511 private function convert_character_to_px( &$size ) {
512 $pixel_conversion = 9;
513
514 $size = round( $pixel_conversion * (int) $size );
515 $size .= 'px';
516 }
517
518 /**
519 * Migrate post and email notification settings into actions
520 */
521 private function migrate_to_16() {
522 $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
523
524 /**
525 * Old email settings format:
526 * email_to: Email or field id
527 * also_email_to: array of fields ids
528 * reply_to: Email, field id, 'custom'
529 * cust_reply_to: string
530 * reply_to_name: field id, 'custom'
531 * cust_reply_to_name: string
532 * plain_text: 0|1
533 * email_message: string or ''
534 * email_subject: string or ''
535 * inc_user_info: 0|1
536 * update_email: 0, 1, 2
537 *
538 * Old autoresponder settings format:
539 * auto_responder: 0|1
540 * ar_email_message: string or ''
541 * ar_email_to: field id
542 * ar_plain_text: 0|1
543 * ar_reply_to_name: string
544 * ar_reply_to: string
545 * ar_email_subject: string
546 * ar_update_email: 0, 1, 2
547 *
548 * New email settings:
549 * post_content: json settings
550 * post_title: form id
551 * post_excerpt: message
552 */
553 foreach ( $forms as $form ) {
554 if ( $form->is_template && $form->default_template ) {
555 // don't migrate the default templates since the email will be added anyway
556 continue;
557 }
558
559 // Format form options
560 $form_options = $form->options;
561 FrmAppHelper::unserialize_or_decode( $form_options );
562
563 // Migrate settings to actions
564 FrmXMLHelper::migrate_form_settings_to_actions( $form_options, $form->id );
565 }
566 }
567
568 private function migrate_to_11() {
569 global $wpdb;
570
571 $forms = FrmDb::get_results( $this->forms, array(), 'id, options' );
572
573 $sending = __( 'Sending', 'formidable' );
574 $img = FrmAppHelper::plugin_url() . '/images/ajax_loader.gif';
575 $old_default_html = <<<DEFAULT_HTML
576 <div class="frm_submit">
577 [if back_button]<input type="submit" value="[back_label]" name="frm_prev_page" formnovalidate="formnovalidate" [back_hook] />[/if back_button]
578 <input type="submit" value="[button_label]" [button_action] />
579 <img class="frm_ajax_loading" src="$img" alt="$sending" style="visibility:hidden;" />
580 </div>
581 DEFAULT_HTML;
582 unset( $sending, $img );
583
584 $new_default_html = FrmFormsHelper::get_default_html( 'submit' );
585 $draft_link = FrmFormsHelper::get_draft_link();
586 foreach ( $forms as $form ) {
587 FrmAppHelper::unserialize_or_decode( $form->options );
588 if ( ! isset( $form->options['submit_html'] ) || empty( $form->options['submit_html'] ) ) {
589 continue;
590 }
591
592 if ( $form->options['submit_html'] != $new_default_html && $form->options['submit_html'] == $old_default_html ) {
593 $form->options['submit_html'] = $new_default_html;
594 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
595 } elseif ( ! strpos( $form->options['submit_html'], 'save_draft' ) ) {
596 $form->options['submit_html'] = preg_replace( '~\<\/div\>(?!.*\<\/div\>)~', $draft_link . "\r\n</div>", $form->options['submit_html'] );
597 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
598 }
599 unset( $form );
600 }
601 }
602 }
603