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

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