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

592 lines 16.9 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 ); // WPCS: unprepared SQL ok.
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 ( ! function_exists( 'libxml_disable_entity_loader' ) ) {
177 // XML import is not enabled on your server.
178 return;
179 }
180
181 $set_err = libxml_use_internal_errors( true );
182 $loader = 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 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 );
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 ); // WPCS: unprepared SQL ok.
226 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->forms ); // WPCS: unprepared SQL ok.
227 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entries ); // WPCS: unprepared SQL ok.
228 $wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entry_metas ); // WPCS: unprepared SQL ok.
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
238 // Delete roles.
239 $frm_roles = FrmAppHelper::frm_capabilities();
240 $roles = get_editable_roles();
241 foreach ( $frm_roles as $frm_role => $frm_role_description ) {
242 foreach ( $roles as $role => $details ) {
243 $wp_roles->remove_cap( $role, $frm_role );
244 unset( $role, $details );
245 }
246 unset( $frm_role, $frm_role_description );
247 }
248 unset( $roles, $frm_roles );
249
250 // delete actions, views, and styles
251
252 // prevent the post deletion from triggering entries to be deleted
253 remove_action( 'before_delete_post', 'FrmProDisplaysController::before_delete_post' );
254 remove_action( 'deleted_post', 'FrmProEntriesController::delete_entry' );
255
256 $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' ) );
257 foreach ( $post_ids as $post_id ) {
258 // Delete's each post.
259 wp_delete_post( $post_id, true );
260 }
261 unset( $post_ids );
262
263 // delete transients
264 delete_transient( 'frmpro_css' );
265 delete_transient( 'frm_options' );
266 delete_transient( 'frmpro_options' );
267
268 $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_%' ) );
269
270 do_action( 'frm_after_uninstall' );
271
272 return true;
273 }
274
275 /**
276 * Move default_blank and clear_on_focus to placeholder.
277 *
278 * @since 4.0
279 */
280 private function migrate_to_97() {
281 $this->migrate_to_placeholder( 'clear_on_focus' );
282 $this->migrate_to_placeholder( 'default_blank' );
283 }
284
285 /**
286 * Move clear_on_focus or default_blank to placeholder.
287 *
288 * @since 4.0
289 */
290 private function migrate_to_placeholder( $type = 'clear_on_focus' ) {
291 $query = array(
292 'field_options like' => '"' . $type . '";s:1:"1";',
293 );
294
295 $fields = FrmDb::get_results( $this->fields, $query, 'id, default_value, field_options, options' );
296
297 foreach ( $fields as $field ) {
298 FrmAppHelper::unserialize_or_decode( $field->field_options );
299 FrmAppHelper::unserialize_or_decode( $field->options );
300 $update_values = FrmXMLHelper::migrate_field_placeholder( $field, $type );
301 if ( empty( $update_values ) ) {
302 continue;
303 }
304
305 FrmField::update( $field->id, $update_values );
306 unset( $field );
307 }
308 }
309
310 /**
311 * Delete uneeded default templates
312 *
313 * @since 3.06
314 */
315 private function migrate_to_90() {
316 $form = FrmForm::getOne( 'contact' );
317 if ( $form && $form->default_template == 1 ) {
318 FrmForm::destroy( 'contact' );
319 }
320 }
321
322 /**
323 * Reverse migration 17 -- Divide by 9
324 *
325 * @since 3.0.05
326 */
327 private function migrate_to_86() {
328
329 $fields = $this->get_fields_with_size();
330
331 foreach ( (array) $fields as $f ) {
332 FrmAppHelper::unserialize_or_decode( $f->field_options );
333 $size = $f->field_options['size'];
334 $this->maybe_convert_migrated_size( $size );
335
336 if ( $size === $f->field_options['size'] ) {
337 continue;
338 }
339
340 $f->field_options['size'] = $size;
341 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
342 unset( $f );
343 }
344
345 // reverse the extra size changes in widgets
346 $widgets = get_option( 'widget_frm_show_form' );
347 if ( empty( $widgets ) ) {
348 return;
349 }
350
351 $this->revert_widget_field_size();
352 }
353
354 private function get_fields_with_size() {
355 $field_types = array(
356 'textarea',
357 'text',
358 'number',
359 'email',
360 'url',
361 'rte',
362 'date',
363 'phone',
364 'password',
365 'image',
366 'tag',
367 'file',
368 );
369
370 $query = array(
371 'type' => $field_types,
372 'field_options like' => 's:4:"size";',
373 'field_options not like' => 's:4:"size";s:0:',
374 );
375
376 return FrmDb::get_results( $this->fields, $query, 'id, field_options' );
377 }
378
379 /**
380 * Reverse the extra size changes in widgets
381 *
382 * @since 3.0.05
383 */
384 private function revert_widget_field_size() {
385 $widgets = get_option( 'widget_frm_show_form' );
386 if ( empty( $widgets ) ) {
387 return;
388 }
389
390 FrmAppHelper::unserialize_or_decode( $widgets );
391 foreach ( $widgets as $k => $widget ) {
392 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
393 continue;
394 }
395
396 $this->maybe_convert_migrated_size( $widgets[ $k ]['size'] );
397 }
398 update_option( 'widget_frm_show_form', $widgets );
399 }
400
401 /**
402 * Divide by 9 to reverse the multiplication
403 *
404 * @since 3.0.05
405 */
406 private function maybe_convert_migrated_size( &$size ) {
407 $has_px_size = ! empty( $size ) && strpos( $size, 'px' );
408 if ( ! $has_px_size ) {
409 return;
410 }
411
412 $int_size = str_replace( 'px', '', $size );
413 if ( ! is_numeric( $int_size ) || (int) $int_size < 900 ) {
414 return;
415 }
416
417 $pixel_conversion = 9;
418
419 $size = round( (int) $int_size / $pixel_conversion );
420 }
421
422 /**
423 * Migrate old styling settings. If sites are using the old
424 * default 400px field width, switch it to 100%
425 *
426 * @since 2.0.4
427 */
428 private function migrate_to_25() {
429 // get the style that was created with the style migration
430 $frm_style = new FrmStyle();
431 $styles = $frm_style->get_all( 'post_date', 'ASC', 1 );
432 if ( empty( $styles ) ) {
433 return;
434 }
435
436 foreach ( $styles as $style ) {
437 if ( $style->post_content['field_width'] == '400px' ) {
438 $style->post_content['field_width'] = '100%';
439 $frm_style->save( (array) $style );
440
441 return;
442 }
443 }
444 }
445
446 /**
447 * Check if the parent_form_id columns exists.
448 * If not, try and add it again
449 *
450 * @since 2.0.2
451 */
452 private function migrate_to_23() {
453 global $wpdb;
454 $exists = $wpdb->get_row( 'SHOW COLUMNS FROM ' . $this->forms . ' LIKE "parent_form_id"' ); // WPCS: unprepared SQL ok.
455 if ( empty( $exists ) ) {
456 $wpdb->query( 'ALTER TABLE ' . $this->forms . ' ADD parent_form_id int(11) default 0' ); // WPCS: unprepared SQL ok.
457 }
458 }
459
460 /**
461 * Change field size from character to pixel -- Multiply by 9
462 */
463 private function migrate_to_17() {
464 $fields = $this->get_fields_with_size();
465
466 foreach ( $fields as $f ) {
467 FrmAppHelper::unserialize_or_decode( $f->field_options );
468 if ( empty( $f->field_options['size'] ) || ! is_numeric( $f->field_options['size'] ) ) {
469 continue;
470 }
471
472 $this->convert_character_to_px( $f->field_options['size'] );
473
474 FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
475 unset( $f );
476 }
477
478 $this->adjust_widget_size();
479 }
480
481 /**
482 * Change the characters in widgets to pixels
483 */
484 private function adjust_widget_size() {
485 $widgets = get_option( 'widget_frm_show_form' );
486 if ( empty( $widgets ) ) {
487 return;
488 }
489
490 FrmAppHelper::unserialize_or_decode( $widgets );
491 foreach ( $widgets as $k => $widget ) {
492 if ( ! is_array( $widget ) || ! isset( $widget['size'] ) ) {
493 continue;
494 }
495 $this->convert_character_to_px( $widgets[ $k ]['size'] );
496 }
497 update_option( 'widget_frm_show_form', $widgets );
498 }
499
500 private function convert_character_to_px( &$size ) {
501 $pixel_conversion = 9;
502
503 $size = round( $pixel_conversion * (int) $size );
504 $size .= 'px';
505 }
506
507 /**
508 * Migrate post and email notification settings into actions
509 */
510 private function migrate_to_16() {
511 $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
512
513 /**
514 * Old email settings format:
515 * email_to: Email or field id
516 * also_email_to: array of fields ids
517 * reply_to: Email, field id, 'custom'
518 * cust_reply_to: string
519 * reply_to_name: field id, 'custom'
520 * cust_reply_to_name: string
521 * plain_text: 0|1
522 * email_message: string or ''
523 * email_subject: string or ''
524 * inc_user_info: 0|1
525 * update_email: 0, 1, 2
526 *
527 * Old autoresponder settings format:
528 * auto_responder: 0|1
529 * ar_email_message: string or ''
530 * ar_email_to: field id
531 * ar_plain_text: 0|1
532 * ar_reply_to_name: string
533 * ar_reply_to: string
534 * ar_email_subject: string
535 * ar_update_email: 0, 1, 2
536 *
537 * New email settings:
538 * post_content: json settings
539 * post_title: form id
540 * post_excerpt: message
541 */
542 foreach ( $forms as $form ) {
543 if ( $form->is_template && $form->default_template ) {
544 // don't migrate the default templates since the email will be added anyway
545 continue;
546 }
547
548 // Format form options
549 $form_options = $form->options;
550 FrmAppHelper::unserialize_or_decode( $form_options );
551
552 // Migrate settings to actions
553 FrmXMLHelper::migrate_form_settings_to_actions( $form_options, $form->id );
554 }
555 }
556
557 private function migrate_to_11() {
558 global $wpdb;
559
560 $forms = FrmDb::get_results( $this->forms, array(), 'id, options' );
561
562 $sending = __( 'Sending', 'formidable' );
563 $img = FrmAppHelper::plugin_url() . '/images/ajax_loader.gif';
564 $old_default_html = <<<DEFAULT_HTML
565 <div class="frm_submit">
566 [if back_button]<input type="submit" value="[back_label]" name="frm_prev_page" formnovalidate="formnovalidate" [back_hook] />[/if back_button]
567 <input type="submit" value="[button_label]" [button_action] />
568 <img class="frm_ajax_loading" src="$img" alt="$sending" style="visibility:hidden;" />
569 </div>
570 DEFAULT_HTML;
571 unset( $sending, $img );
572
573 $new_default_html = FrmFormsHelper::get_default_html( 'submit' );
574 $draft_link = FrmFormsHelper::get_draft_link();
575 foreach ( $forms as $form ) {
576 FrmAppHelper::unserialize_or_decode( $form->options );
577 if ( ! isset( $form->options['submit_html'] ) || empty( $form->options['submit_html'] ) ) {
578 continue;
579 }
580
581 if ( $form->options['submit_html'] != $new_default_html && $form->options['submit_html'] == $old_default_html ) {
582 $form->options['submit_html'] = $new_default_html;
583 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
584 } elseif ( ! strpos( $form->options['submit_html'], 'save_draft' ) ) {
585 $form->options['submit_html'] = preg_replace( '~\<\/div\>(?!.*\<\/div\>)~', $draft_link . "\r\n</div>", $form->options['submit_html'] );
586 $wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
587 }
588 unset( $form );
589 }
590 }
591 }
592