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

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