Completed
Push — master ( 659afe...10163c )
by Jamie
04:19
created

FrmDb::migrate_data()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 2
dl 0
loc 9
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
class FrmDb {
4
    var $fields;
5
    var $forms;
6
    var $entries;
7
    var $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( $old_db_version = false ) {
22
        global $wpdb;
23
        //$frm_db_version is the version of the database we're moving to
24
        $frm_db_version = FrmAppHelper::$db_version;
25
        $old_db_version = (float) $old_db_version;
26
        if ( ! $old_db_version ) {
27
            $old_db_version = get_option('frm_db_version');
28
        }
29
30
        if ( $frm_db_version != $old_db_version ) {
31
			// update rewrite rules for views and other custom post types
32
			flush_rewrite_rules();
33
34
			require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
35
36
            $this->create_tables();
37
            $this->migrate_data($frm_db_version, $old_db_version);
38
39
            /***** SAVE DB VERSION *****/
40
            update_option('frm_db_version', $frm_db_version);
41
42
            /**** ADD/UPDATE DEFAULT TEMPLATES ****/
43
            FrmXMLController::add_default_templates();
44
        }
45
46
        do_action('frm_after_install');
47
48
        /**** update the styling settings ****/
49
		if ( is_admin() && function_exists( 'get_filesystem_method' ) ) {
50
			$frm_style = new FrmStyle();
51
			$frm_style->update( 'default' );
52
		}
53
    }
54
55
    public function collation() {
56
        global $wpdb;
57
        if ( ! $wpdb->has_cap( 'collation' ) ) {
58
            return '';
59
        }
60
61
        $charset_collate = '';
62
		if ( ! empty( $wpdb->charset ) ) {
63
			$charset_collate .= ' DEFAULT CHARACTER SET ' . $wpdb->charset;
64
		}
65
66
		if ( ! empty( $wpdb->collate ) ) {
67
			$charset_collate .= ' COLLATE ' . $wpdb->collate;
68
		}
69
70
        return $charset_collate;
71
    }
72
73
    private function create_tables() {
74
        $charset_collate = $this->collation();
75
        $sql = array();
76
77
        /* Create/Upgrade Fields Table */
78
		$sql[] = 'CREATE TABLE ' . $this->fields . ' (
79
                id int(11) NOT NULL auto_increment,
80
				field_key varchar(100) default NULL,
81
                name text default NULL,
82
                description longtext default NULL,
83
                type text default NULL,
84
                default_value longtext default NULL,
85
                options longtext default NULL,
86
                field_order int(11) default 0,
87
                required int(1) default NULL,
88
                field_options longtext default NULL,
89
                form_id int(11) default NULL,
90
                created_at datetime NOT NULL,
91
                PRIMARY KEY  (id),
92
                KEY form_id (form_id),
93
                UNIQUE KEY field_key (field_key)
94
        )';
95
96
        /* Create/Upgrade Forms Table */
97
		$sql[] = 'CREATE TABLE ' . $this->forms . ' (
98
                id int(11) NOT NULL auto_increment,
99
				form_key varchar(100) default NULL,
100
                name varchar(255) default NULL,
101
                description text default NULL,
102
                parent_form_id int(11) default 0,
103
                logged_in tinyint(1) default NULL,
104
                editable tinyint(1) default NULL,
105
                is_template tinyint(1) default 0,
106
                default_template tinyint(1) default 0,
107
                status varchar(255) default NULL,
108
                options longtext default NULL,
109
                created_at datetime NOT NULL,
110
                PRIMARY KEY  (id),
111
                UNIQUE KEY form_key (form_key)
112
        )';
113
114
        /* Create/Upgrade Items Table */
115
		$sql[] = 'CREATE TABLE ' . $this->entries . ' (
116
                id int(11) NOT NULL auto_increment,
117
				item_key varchar(100) default NULL,
118
                name varchar(255) default NULL,
119
                description text default NULL,
120
                ip text default NULL,
121
                form_id int(11) default NULL,
122
                post_id int(11) default NULL,
123
                user_id int(11) default NULL,
124
                parent_item_id int(11) default 0,
125
                is_draft tinyint(1) default 0,
126
                updated_by int(11) default NULL,
127
                created_at datetime NOT NULL,
128
                updated_at datetime NOT NULL,
129
                PRIMARY KEY  (id),
130
                KEY form_id (form_id),
131
                KEY post_id (post_id),
132
                KEY user_id (user_id),
133
                KEY parent_item_id (parent_item_id),
134
                UNIQUE KEY item_key (item_key)
135
        )';
136
137
        /* Create/Upgrade Meta Table */
138
		$sql[] = 'CREATE TABLE ' . $this->entry_metas . ' (
139
                id int(11) NOT NULL auto_increment,
140
                meta_value longtext default NULL,
141
                field_id int(11) NOT NULL,
142
                item_id int(11) NOT NULL,
143
                created_at datetime NOT NULL,
144
                PRIMARY KEY  (id),
145
                KEY field_id (field_id),
146
                KEY item_id (item_id)
147
        )';
148
149
        foreach ( $sql as $q ) {
150
			if ( function_exists( 'dbDelta' ) ) {
151
				dbDelta( $q . $charset_collate . ';' );
152
			} else {
153
				global $wpdb;
154
				$wpdb->query( $q . $charset_collate );
155
			}
156
            unset($q);
157
        }
158
    }
159
160
    /**
161
     * @param integer $frm_db_version
162
     */
163
	private function migrate_data( $frm_db_version, $old_db_version ) {
164
		$migrations = array( 4, 6, 11, 16, 17, 23, 25 );
165
        foreach ( $migrations as $migration ) {
166
            if ( $frm_db_version >= $migration && $old_db_version < $migration ) {
167
				$function_name = 'migrate_to_' . $migration;
168
                $this->$function_name();
169
            }
170
        }
171
    }
172
173
    /**
174
     * Change array into format $wpdb->prepare can use
175
     */
176
    public static function get_where_clause_and_values( &$args, $starts_with = ' WHERE ' ) {
177
        if ( empty($args) ) {
178
			// add an arg to prevent prepare from failing
179
			$args = array( 'where' => $starts_with . '1=%d', 'values' => array( 1 ) );
180
			return;
181
        }
182
183
		$where = '';
184
		$values = array();
185
186
		if ( is_array( $args ) ) {
187
			$base_where = $starts_with;
188
			self::parse_where_from_array( $args, $base_where, $where, $values );
189
		}
190
191
		$args = compact( 'where', 'values' );
192
    }
193
194
    /**
195
     * @param string $base_where
196
     * @param string $where
197
     */
198
    public static function parse_where_from_array( $args, $base_where, &$where, &$values ) {
199
        $condition = ' AND';
200
        if ( isset( $args['or'] ) ) {
201
            $condition = ' OR';
202
            unset( $args['or'] );
203
        }
204
205
        foreach ( $args as $key => $value ) {
206
            $where .= empty( $where ) ? $base_where : $condition;
207
            $array_inc_null = ( ! is_numeric( $key ) && is_array( $value ) && in_array( null, $value ) );
208
            if ( is_numeric( $key ) || $array_inc_null ) {
209
                $where .= ' ( ';
210
                $nested_where = '';
211
                if ( $array_inc_null ) {
212
                    foreach ( $value as $val ) {
213
                        self::parse_where_from_array( array( $key => $val, 'or' => 1 ), '', $nested_where, $values );
214
                    }
215
                } else {
216
                    self::parse_where_from_array( $value, '', $nested_where, $values );
217
                }
218
                $where .= $nested_where;
219
                $where .= ' ) ';
220
            } else {
221
                self::interpret_array_to_sql( $key, $value, $where, $values );
222
            }
223
        }
224
    }
225
226
    /**
227
     * @param string $key
228
     * @param string $where
229
     */
230
    private static function interpret_array_to_sql( $key, $value, &$where, &$values ) {
231
		$key = trim( $key );
232
233
        if ( strpos( $key, 'created_at' ) !== false || strpos( $key, 'updated_at' ) !== false  ) {
234
            $k = explode(' ', $key);
235
            $where .= ' DATE_FORMAT(' . reset( $k ) . ', %s) ' . str_replace( reset( $k ), '', $key );
236
            $values[] = '%Y-%m-%d %H:%i:%s';
237
        } else {
238
			$where .= ' ' . $key;
239
        }
240
241
		$lowercase_key = explode( ' ', strtolower( $key ) );
242
		$lowercase_key = end( $lowercase_key );
243
244
        if ( is_array( $value ) ) {
245
            // translate array of values to "in"
246
			if ( strpos( $lowercase_key, 'like' ) !== false ) {
247
				$where = preg_replace('/' . $key . '$/', '', $where);
248
				$where .= '(';
249
				$start = true;
250
				foreach ( $value as $v ) {
251
					if ( ! $start ) {
252
						$where .= ' OR ';
253
					}
254
					$start = false;
255
					$where .= $key . ' %s';
256
					$values[] = '%' . FrmAppHelper::esc_like( $v ) . '%';
257
				}
258
				$where .= ')';
259
			} else if ( ! empty( $value ) ) {
260
				$where .= ' in (' . FrmAppHelper::prepare_array_values( $value, '%s' ) . ')';
261
				$values = array_merge( $values, $value );
262
			}
263
        } else if ( strpos( $lowercase_key, 'like' ) !== false ) {
264
			/**
265
			 * Allow string to start or end with the value
266
			 * If the key is like% then skip the first % for starts with
267
			 * If the key is %like then skip the last % for ends with
268
			 */
269
			$start = $end = '%';
270
			if ( $lowercase_key == 'like%' ) {
271
				$start = '';
272
				$where = rtrim( $where, '%' );
273
			} else if ( $lowercase_key == '%like' ) {
274
				$end = '';
275
				$where = rtrim( rtrim( $where, '%like' ), '%LIKE' );
276
				$where .= 'like';
277
			}
278
279
			$where .= ' %s';
280
			$values[] = $start . FrmAppHelper::esc_like( $value ) . $end;
281
282
        } else if ( $value === null ) {
283
            $where .= ' IS NULL';
284
        } else {
285
			// allow a - to prevent = from being added
286
			if ( substr( $key, -1 ) == '-' ) {
287
				$where = rtrim( $where, '-' );
288
			} else {
289
				$where .= '=';
290
			}
291
292
			self::add_query_placeholder( $key, $value, $where );
293
294
            $values[] = $value;
295
        }
296
    }
297
298
	/**
299
	 * Add %d, or %s to query
300
	 *
301
	 * @since 2.02.05
302
	 * @param int|string $value
303
	 * @param string $where
304
	 */
305
    private static function add_query_placeholder( $key, $value, &$where ) {
306
		if ( is_numeric( $value ) && strpos( $key, 'meta_value' ) === false ) {
307
			$where .= '%d';
308
		} else {
309
			$where .= '%s';
310
		}
311
	}
312
313
    /**
314
     * @param string $table
315
     */
316
    public static function get_count( $table, $where = array(), $args = array() ) {
317
        $count = self::get_var( $table, $where, 'COUNT(*)', $args );
318
        return $count;
319
    }
320
321
    public static function get_var( $table, $where = array(), $field = 'id', $args = array(), $limit = '', $type = 'var' ) {
322
        $group = '';
323
        self::get_group_and_table_name( $table, $group );
324
		self::convert_options_to_array( $args, '', $limit );
325
326
		$query = 'SELECT ' . $field . ' FROM ' . $table;
327
		if ( is_array( $where ) || empty( $where ) ) {
328
			// only separate into array values and query string if is array
329
        	self::get_where_clause_and_values( $where );
330
			global $wpdb;
331
			$query = $wpdb->prepare( $query . $where['where'] . ' ' . implode( ' ', $args ), $where['values'] );
332
		} else {
333
			/**
334
			 * Allow the $where to be prepared before we recieve it here.
335
			 * This is a fallback for reverse compatability, but is not recommended
336
			 */
337
			_deprecated_argument( 'where', '2.0', __( 'Use the query in an array format so it can be properly prepared.', 'formidable' ) );
338
			$query .= $where . ' ' . implode( ' ', $args );
339
		}
340
341
		$cache_key = str_replace( array( ' ', ',' ), '_', trim( implode( '_', FrmAppHelper::array_flatten( $where ) ) . implode( '_', $args ) . $field . '_' . $type, ' WHERE' ) );
342
		$results = FrmAppHelper::check_cache( $cache_key, $group, $query, 'get_' . $type );
343
        return $results;
344
    }
345
346
    /**
347
     * @param string $table
348
     * @param array $where
349
     */
350
    public static function get_col( $table, $where = array(), $field = 'id', $args = array(), $limit = '' ) {
351
        return self::get_var( $table, $where, $field, $args, $limit, 'col' );
352
    }
353
354
    /**
355
     * @since 2.0
356
     * @param string $table
357
     */
358
    public static function get_row( $table, $where = array(), $fields = '*', $args = array() ) {
359
        $args['limit'] = 1;
360
        return self::get_var( $table, $where, $fields, $args, '', 'row' );
361
    }
362
363
    /**
364
     * @param string $table
365
     */
366
    public static function get_one_record( $table, $args = array(), $fields = '*', $order_by = '' ) {
367
        _deprecated_function( __FUNCTION__, '2.0', 'FrmDb::get_row' );
368
		return self::get_var( $table, $args, $fields, array( 'order_by' => $order_by, 'limit' => 1 ), '', 'row' );
369
    }
370
371
    public static function get_records( $table, $args = array(), $order_by = '', $limit = '', $fields = '*' ) {
372
        _deprecated_function( __FUNCTION__, '2.0', 'FrmDb::get_results' );
373
        return self::get_results( $table, $args, $fields, compact('order_by', 'limit') );
374
    }
375
376
    /**
377
     * Prepare a key/value array before DB call
378
     * @since 2.0
379
     * @param string $table
380
     */
381
    public static function get_results( $table, $where = array(), $fields = '*', $args = array() ) {
382
        return self::get_var( $table, $where, $fields, $args, '', 'results' );
383
    }
384
385
	/**
386
	 * Check for like, not like, in, not in, =, !=, >, <, <=, >=
387
	 * Return a value to append to the where array key
388
	 *
389
	 * @return string
390
	 */
391
	public static function append_where_is( $where_is ) {
392
		$switch_to = array(
393
			'='		=> '',
394
			'!=' 	=> '!',
395
			'<='	=> '<',
396
			'>='	=> '>',
397
			'like'	=> 'like',
398
			'not like' => 'not like',
399
			'in'	=> '',
400
			'not in' => 'not',
401
			'like%'	=> 'like%',
402
			'%like'	=> '%like',
403
		);
404
405
		$where_is = strtolower( $where_is );
406
		if ( isset( $switch_to[ $where_is ] ) ) {
407
			return ' ' . $switch_to[ $where_is ];
408
		}
409
410
		// > and < need a little more work since we don't want them switched to >= and <=
411
		if ( $where_is == '>' || $where_is == '<' ) {
412
			return ' ' . $where_is . '-'; // the - indicates that the = should not be added later
413
		}
414
415
		// fallback to = if the query is none of these
416
		return '';
417
	}
418
419
    /**
420
     * Get 'frm_forms' from wp_frm_forms or a longer table param that includes a join
421
     * Also add the wpdb->prefix to the table if it's missing
422
     *
423
     * @param string $table
424
     * @param string $group
425
     */
426
    private static function get_group_and_table_name( &$table, &$group ) {
427
		global $wpdb, $wpmuBaseTablePrefix;
428
429
        $table_parts = explode(' ', $table);
430
        $group = reset($table_parts);
431
        $group = str_replace( $wpdb->prefix, '', $group );
432
433
		$prefix = $wpmuBaseTablePrefix ? $wpmuBaseTablePrefix : $wpdb->base_prefix;
434
		$group = str_replace( $prefix, '', $group );
435
436
        if ( $group == $table ) {
437
            $table = $wpdb->prefix . $table;
438
        }
439
440
		// switch to singular group name
441
		$group = rtrim( $group, 's' );
442
    }
443
444
    private static function convert_options_to_array( &$args, $order_by = '', $limit = '' ) {
445
        if ( ! is_array($args) ) {
446
			$args = array( 'order_by' => $args );
447
        }
448
449
        if ( ! empty( $order_by ) ) {
450
            $args['order_by'] = $order_by;
451
        }
452
453
        if ( ! empty( $limit ) ) {
454
            $args['limit'] = $limit;
455
        }
456
457
        $temp_args = $args;
458
        foreach ( $temp_args as $k => $v ) {
459
            if ( $v == '' ) {
460
				unset( $args[ $k ] );
461
                continue;
462
            }
463
464
            if ( $k == 'limit' ) {
465
				$args[ $k ] = FrmAppHelper::esc_limit( $v );
466
            }
467
            $db_name = strtoupper( str_replace( '_', ' ', $k ) );
468
            if ( strpos( $v, $db_name ) === false ) {
469
				$args[ $k ] = $db_name . ' ' . $v;
470
            }
471
        }
472
473
		// Make sure LIMIT is the last argument
474
		if ( isset( $args['order_by'] ) && isset( $args['limit'] ) ) {
475
			$temp_limit = $args['limit'];
476
			unset( $args['limit'] );
477
			$args['limit'] = $temp_limit;
478
		}
479
    }
480
481
    public function uninstall() {
482
		if ( ! current_user_can( 'administrator' ) ) {
483
            $frm_settings = FrmAppHelper::get_settings();
484
            wp_die($frm_settings->admin_permission);
485
        }
486
487
        global $wpdb, $wp_roles;
488
489
		$wpdb->query( 'DROP TABLE IF EXISTS ' . $this->fields );
490
		$wpdb->query( 'DROP TABLE IF EXISTS ' . $this->forms );
491
		$wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entries );
492
		$wpdb->query( 'DROP TABLE IF EXISTS ' . $this->entry_metas );
493
494
        delete_option('frm_options');
495
        delete_option('frm_db_version');
496
497
        //delete roles
498
        $frm_roles = FrmAppHelper::frm_capabilities();
499
        $roles = get_editable_roles();
500
        foreach ( $frm_roles as $frm_role => $frm_role_description ) {
501
            foreach ( $roles as $role => $details ) {
502
                $wp_roles->remove_cap( $role, $frm_role );
503
                unset($role, $details);
504
    		}
505
    		unset($frm_role, $frm_role_description);
506
		}
507
		unset($roles, $frm_roles);
508
509
		// delete actions, views, and styles
510
511
		// prevent the post deletion from triggering entries to be deleted
512
		remove_action( 'before_delete_post', 'FrmProDisplaysController::before_delete_post' );
513
		remove_action( 'deleted_post', 'FrmProEntriesController::delete_entry' );
514
515
		$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' ) );
516
		foreach ( $post_ids as $post_id ) {
517
			// Delete's each post.
518
			wp_delete_post( $post_id, true );
519
		}
520
		unset( $post_ids );
521
522
		// delete transients
523
		delete_transient( 'frmpro_css' );
524
		delete_transient( 'frm_options' );
525
		delete_transient( 'frmpro_options' );
526
527
		$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_%' ) );
528
529
        do_action('frm_after_uninstall');
530
        return true;
531
    }
532
533
	/**
534
	 * Migrate old styling settings. If sites are using the old
535
	 * default 400px field width, switch it to 100%
536
	 *
537
	 * @since 2.0.4
538
	 */
539
	private function migrate_to_25() {
540
		// get the style that was created with the style migration
541
		$frm_style = new FrmStyle();
542
		$styles = $frm_style->get_all( 'post_date', 'ASC', 1 );
543
		if ( empty( $styles ) ) {
544
			return;
545
		}
546
547
		foreach ( $styles as $style ) {
548
			if ( $style->post_content['field_width'] == '400px' ) {
549
				$style->post_content['field_width'] = '100%';
550
				$frm_style->save( (array) $style );
551
				return;
552
			}
553
		}
554
	}
555
556
	/**
557
	 * Check if the parent_form_id columns exists.
558
	 * If not, try and add it again
559
	 *
560
	 * @since 2.0.2
561
	 */
562
	private function migrate_to_23() {
563
		global $wpdb;
564
		$exists = $wpdb->get_row( 'SHOW COLUMNS FROM ' . $this->forms . ' LIKE "parent_form_id"' );
565
		if ( empty( $exists ) ) {
566
			$wpdb->query( 'ALTER TABLE ' . $this->forms . ' ADD parent_form_id int(11) default 0' );
567
		}
568
	}
569
570
    /**
571
     * Change field size from character to pixel -- Multiply by 9
572
     */
573
    private function migrate_to_17() {
574
        global $wpdb;
575
		$pixel_conversion = 9;
576
577
        // Get query arguments
578
		$field_types = array( 'textarea', 'text', 'number', 'email', 'url', 'rte', 'date', 'phone', 'password', 'image', 'tag', 'file' );
579
		$query = array( 'type' => $field_types, 'field_options like' => 's:4:"size";', 'field_options not like' => 's:4:"size";s:0:' );
580
581
        // Get results
582
		$fields = FrmDb::get_results( $this->fields, $query, 'id, field_options' );
583
584
        $updated = 0;
585
        foreach ( $fields as $f ) {
586
            $f->field_options = maybe_unserialize($f->field_options);
587
            if ( empty($f->field_options['size']) || ! is_numeric($f->field_options['size']) ) {
588
                continue;
589
            }
590
591
			$f->field_options['size'] = round( $pixel_conversion * (int) $f->field_options['size'] );
592
            $f->field_options['size'] .= 'px';
593
            $u = FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
594
            if ( $u ) {
595
                $updated++;
596
            }
597
            unset($f);
598
        }
599
600
        // Change the characters in widgets to pixels
601
        $widgets = get_option('widget_frm_show_form');
602
        if ( empty($widgets) ) {
603
            return;
604
        }
605
606
        $widgets = maybe_unserialize($widgets);
607
        foreach ( $widgets as $k => $widget ) {
608
            if ( ! is_array($widget) || ! isset($widget['size']) ) {
609
                continue;
610
            }
611
			$size = round( $pixel_conversion * (int) $widget['size'] );
612
            $size .= 'px';
613
			$widgets[ $k ]['size'] = $size;
614
        }
615
        update_option('widget_frm_show_form', $widgets);
616
    }
617
618
    /**
619
     * Migrate post and email notification settings into actions
620
     */
621
    private function migrate_to_16() {
622
        global $wpdb;
623
624
        $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
625
626
        /**
627
        * Old email settings format:
628
        * email_to: Email or field id
629
        * also_email_to: array of fields ids
630
        * reply_to: Email, field id, 'custom'
631
        * cust_reply_to: string
632
        * reply_to_name: field id, 'custom'
633
        * cust_reply_to_name: string
634
        * plain_text: 0|1
635
        * email_message: string or ''
636
        * email_subject: string or ''
637
        * inc_user_info: 0|1
638
        * update_email: 0, 1, 2
639
        *
640
        * Old autoresponder settings format:
641
        * auto_responder: 0|1
642
        * ar_email_message: string or ''
643
        * ar_email_to: field id
644
        * ar_plain_text: 0|1
645
        * ar_reply_to_name: string
646
        * ar_reply_to: string
647
        * ar_email_subject: string
648
        * ar_update_email: 0, 1, 2
649
        *
650
        * New email settings:
651
        * post_content: json settings
652
        * post_title: form id
653
        * post_excerpt: message
654
        *
655
        */
656
657
        foreach ( $forms as $form ) {
658
			if ( $form->is_template && $form->default_template ) {
659
				// don't migrate the default templates since the email will be added anyway
660
				continue;
661
			}
662
663
            // Format form options
664
            $form_options = maybe_unserialize($form->options);
665
666
            // Migrate settings to actions
667
            FrmXMLHelper::migrate_form_settings_to_actions( $form_options, $form->id );
668
        }
669
    }
670
671
    private function migrate_to_11() {
672
        global $wpdb;
673
674
        $forms = FrmDb::get_results( $this->forms, array(), 'id, options');
675
676
        $sending = __( 'Sending', 'formidable' );
677
		$img = FrmAppHelper::plugin_url() . '/images/ajax_loader.gif';
678
        $old_default_html = <<<DEFAULT_HTML
679
<div class="frm_submit">
680
[if back_button]<input type="submit" value="[back_label]" name="frm_prev_page" formnovalidate="formnovalidate" [back_hook] />[/if back_button]
681
<input type="submit" value="[button_label]" [button_action] />
682
<img class="frm_ajax_loading" src="$img" alt="$sending" style="visibility:hidden;" />
683
</div>
684
DEFAULT_HTML;
685
        unset($sending, $img);
686
687
        $new_default_html = FrmFormsHelper::get_default_html('submit');
688
        $draft_link = FrmFormsHelper::get_draft_link();
689
		foreach ( $forms as $form ) {
690
            $form->options = maybe_unserialize($form->options);
691
            if ( ! isset($form->options['submit_html']) || empty($form->options['submit_html']) ) {
692
                continue;
693
            }
694
695
            if ( $form->options['submit_html'] != $new_default_html && $form->options['submit_html'] == $old_default_html ) {
696
                $form->options['submit_html'] = $new_default_html;
697
				$wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
698
			} else if ( ! strpos( $form->options['submit_html'], 'save_draft' ) ) {
699
				$form->options['submit_html'] = preg_replace( '~\<\/div\>(?!.*\<\/div\>)~', $draft_link . "\r\n</div>", $form->options['submit_html'] );
700
				$wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
701
            }
702
            unset($form);
703
        }
704
        unset($forms);
705
    }
706
707
    private function migrate_to_6() {
708
        global $wpdb;
709
710
		$no_save = array_merge( FrmField::no_save_fields(), array( 'form', 'hidden', 'user_id' ) );
711
		$fields = FrmDb::get_results( $this->fields, array( 'type NOT' => $no_save ), 'id, field_options' );
712
713
        $default_html = <<<DEFAULT_HTML
714
<div id="frm_field_[id]_container" class="form-field [required_class] [error_class]">
715
    <label class="frm_pos_[label_position]">[field_name]
716
        <span class="frm_required">[required_label]</span>
717
    </label>
718
    [input]
719
    [if description]<div class="frm_description">[description]</div>[/if description]
720
</div>
721
DEFAULT_HTML;
722
723
        $old_default_html = <<<DEFAULT_HTML
724
<div id="frm_field_[id]_container" class="form-field [required_class] [error_class]">
725
    <label class="frm_pos_[label_position]">[field_name]
726
        <span class="frm_required">[required_label]</span>
727
    </label>
728
    [input]
729
    [if description]<p class="frm_description">[description]</p>[/if description]
730
</div>
731
DEFAULT_HTML;
732
733
        $new_default_html = FrmFieldsHelper::get_default_html('text');
734
        foreach ( $fields as $field ) {
735
            $field->field_options = maybe_unserialize($field->field_options);
736
			if ( ! FrmField::is_option_empty( $field, 'custom_html' ) || $field->field_options['custom_html'] == $default_html || $field->field_options['custom_html'] == $old_default_html ) {
737
                $field->field_options['custom_html'] = $new_default_html;
738
				$wpdb->update( $this->fields, array( 'field_options' => maybe_serialize( $field->field_options ) ), array( 'id' => $field->id ) );
739
            }
740
            unset($field);
741
        }
742
        unset($default_html, $old_default_html, $fields);
743
    }
744
745
    private function migrate_to_4() {
746
        global $wpdb;
747
		$user_ids = FrmEntryMeta::getAll( array( 'fi.type' => 'user_id' ) );
748
        foreach ( $user_ids as $user_id ) {
749
			$wpdb->update( $this->entries, array( 'user_id' => $user_id->meta_value ), array( 'id' => $user_id->item_id ) );
750
        }
751
    }
752
}
753