Completed
Push — master ( 654cda...c129fe )
by Stephanie
03:51 queued 01:07
created

FrmDb::migrate_to_16()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 49
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
648
            $f->field_options = maybe_unserialize($f->field_options);
649
            if ( empty($f->field_options['size']) || ! is_numeric($f->field_options['size']) ) {
650
                continue;
651
            }
652
653
			$f->field_options['size'] = round( $pixel_conversion * (int) $f->field_options['size'] );
654
            $f->field_options['size'] .= 'px';
655
            $u = FrmField::update( $f->id, array( 'field_options' => $f->field_options ) );
656
            if ( $u ) {
657
                $updated++;
658
            }
659
            unset($f);
660
        }
661
662
        // Change the characters in widgets to pixels
663
        $widgets = get_option('widget_frm_show_form');
664
        if ( empty($widgets) ) {
665
            return;
666
        }
667
668
        $widgets = maybe_unserialize($widgets);
669
        foreach ( $widgets as $k => $widget ) {
670
            if ( ! is_array($widget) || ! isset($widget['size']) ) {
671
                continue;
672
            }
673
			$size = round( $pixel_conversion * (int) $widget['size'] );
674
            $size .= 'px';
675
			$widgets[ $k ]['size'] = $size;
676
        }
677
        update_option('widget_frm_show_form', $widgets);
678
    }
679
680
    /**
681
     * Migrate post and email notification settings into actions
682
     */
683
    private function migrate_to_16() {
684
        global $wpdb;
685
686
        $forms = FrmDb::get_results( $this->forms, array(), 'id, options, is_template, default_template' );
687
688
        /**
689
        * Old email settings format:
690
        * email_to: Email or field id
691
        * also_email_to: array of fields ids
692
        * reply_to: Email, field id, 'custom'
693
        * cust_reply_to: string
694
        * reply_to_name: field id, 'custom'
695
        * cust_reply_to_name: string
696
        * plain_text: 0|1
697
        * email_message: string or ''
698
        * email_subject: string or ''
699
        * inc_user_info: 0|1
700
        * update_email: 0, 1, 2
701
        *
702
        * Old autoresponder settings format:
703
        * auto_responder: 0|1
704
        * ar_email_message: string or ''
705
        * ar_email_to: field id
706
        * ar_plain_text: 0|1
707
        * ar_reply_to_name: string
708
        * ar_reply_to: string
709
        * ar_email_subject: string
710
        * ar_update_email: 0, 1, 2
711
        *
712
        * New email settings:
713
        * post_content: json settings
714
        * post_title: form id
715
        * post_excerpt: message
716
        *
717
        */
718
719
        foreach ( $forms as $form ) {
0 ignored issues
show
Bug introduced by
The expression $forms of type array|null|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
720
			if ( $form->is_template && $form->default_template ) {
721
				// don't migrate the default templates since the email will be added anyway
722
				continue;
723
			}
724
725
            // Format form options
726
            $form_options = maybe_unserialize($form->options);
727
728
            // Migrate settings to actions
729
            FrmXMLHelper::migrate_form_settings_to_actions( $form_options, $form->id );
730
        }
731
    }
732
733
    private function migrate_to_11() {
734
        global $wpdb;
735
736
        $forms = FrmDb::get_results( $this->forms, array(), 'id, options');
737
738
        $sending = __( 'Sending', 'formidable' );
739
		$img = FrmAppHelper::plugin_url() . '/images/ajax_loader.gif';
740
        $old_default_html = <<<DEFAULT_HTML
741
<div class="frm_submit">
742
[if back_button]<input type="submit" value="[back_label]" name="frm_prev_page" formnovalidate="formnovalidate" [back_hook] />[/if back_button]
743
<input type="submit" value="[button_label]" [button_action] />
744
<img class="frm_ajax_loading" src="$img" alt="$sending" style="visibility:hidden;" />
745
</div>
746
DEFAULT_HTML;
747
        unset($sending, $img);
748
749
        $new_default_html = FrmFormsHelper::get_default_html('submit');
750
        $draft_link = FrmFormsHelper::get_draft_link();
751
		foreach ( $forms as $form ) {
0 ignored issues
show
Bug introduced by
The expression $forms of type array|null|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
752
            $form->options = maybe_unserialize($form->options);
753
            if ( ! isset($form->options['submit_html']) || empty($form->options['submit_html']) ) {
754
                continue;
755
            }
756
757
            if ( $form->options['submit_html'] != $new_default_html && $form->options['submit_html'] == $old_default_html ) {
758
                $form->options['submit_html'] = $new_default_html;
759
				$wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
760
			} else if ( ! strpos( $form->options['submit_html'], 'save_draft' ) ) {
761
				$form->options['submit_html'] = preg_replace( '~\<\/div\>(?!.*\<\/div\>)~', $draft_link . "\r\n</div>", $form->options['submit_html'] );
762
				$wpdb->update( $this->forms, array( 'options' => serialize( $form->options ) ), array( 'id' => $form->id ) );
763
            }
764
            unset($form);
765
        }
766
        unset($forms);
767
    }
768
769
    private function migrate_to_6() {
770
        global $wpdb;
771
772
		$no_save = array_merge( FrmField::no_save_fields(), array( 'form', 'hidden', 'user_id' ) );
773
		$fields = FrmDb::get_results( $this->fields, array( 'type NOT' => $no_save ), 'id, field_options' );
774
775
        $default_html = <<<DEFAULT_HTML
776
<div id="frm_field_[id]_container" class="form-field [required_class] [error_class]">
777
    <label class="frm_pos_[label_position]">[field_name]
778
        <span class="frm_required">[required_label]</span>
779
    </label>
780
    [input]
781
    [if description]<div class="frm_description">[description]</div>[/if description]
782
</div>
783
DEFAULT_HTML;
784
785
        $old_default_html = <<<DEFAULT_HTML
786
<div id="frm_field_[id]_container" class="form-field [required_class] [error_class]">
787
    <label class="frm_pos_[label_position]">[field_name]
788
        <span class="frm_required">[required_label]</span>
789
    </label>
790
    [input]
791
    [if description]<p class="frm_description">[description]</p>[/if description]
792
</div>
793
DEFAULT_HTML;
794
795
        $new_default_html = FrmFieldsHelper::get_default_html('text');
796
        foreach ( $fields as $field ) {
0 ignored issues
show
Bug introduced by
The expression $fields of type array|null|string|object is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
797
            $field->field_options = maybe_unserialize($field->field_options);
798
			if ( ! FrmField::is_option_empty( $field, 'custom_html' ) || $field->field_options['custom_html'] == $default_html || $field->field_options['custom_html'] == $old_default_html ) {
799
                $field->field_options['custom_html'] = $new_default_html;
800
				$wpdb->update( $this->fields, array( 'field_options' => maybe_serialize( $field->field_options ) ), array( 'id' => $field->id ) );
801
            }
802
            unset($field);
803
        }
804
        unset($default_html, $old_default_html, $fields);
805
    }
806
807
    private function migrate_to_4() {
808
        global $wpdb;
809
		$user_ids = FrmEntryMeta::getAll( array( 'fi.type' => 'user_id' ) );
810
        foreach ( $user_ids as $user_id ) {
811
			$wpdb->update( $this->entries, array( 'user_id' => $user_id->meta_value ), array( 'id' => $user_id->item_id ) );
812
        }
813
    }
814
815
	public static function get_one_record( $table, $args = array(), $fields = '*', $order_by = '' ) {
816
		_deprecated_function( __FUNCTION__, '2.0', 'FrmDb::get_row' );
817
		return self::get_var( $table, $args, $fields, array( 'order_by' => $order_by, 'limit' => 1 ), '', 'row' );
818
	}
819
820
	public static function get_records( $table, $args = array(), $order_by = '', $limit = '', $fields = '*' ) {
821
		_deprecated_function( __FUNCTION__, '2.0', 'FrmDb::get_results' );
822
		return self::get_results( $table, $args, $fields, compact('order_by', 'limit') );
823
	}
824
}
825