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

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