Completed
Push — master ( 030e64...7d42b5 )
by Stephanie
02:43
created

FrmField::get_option_in_object()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
if ( ! defined('ABSPATH') ) {
3
	die( 'You are not allowed to call this page directly.' );
4
}
5
6
class FrmField {
7
8
    static $use_cache = true;
9
	static $transient_size = 200;
10
11
	public static function field_selection() {
12
		$fields = apply_filters('frm_available_fields', array(
13
			'text'      => __( 'Single Line Text', 'formidable' ),
14
			'textarea'  => __( 'Paragraph Text', 'formidable' ),
15
			'checkbox'  => __( 'Checkboxes', 'formidable' ),
16
			'radio'     => __( 'Radio Buttons', 'formidable' ),
17
			'select'    => __( 'Dropdown', 'formidable' ),
18
			'email'     => __( 'Email Address', 'formidable' ),
19
			'url'       => __( 'Website/URL', 'formidable' ),
20
			'captcha'   => __( 'reCAPTCHA', 'formidable' ),
21
		));
22
23
		return $fields;
24
	}
25
26
	public static function pro_field_selection() {
27
		return apply_filters('frm_pro_available_fields', array(
28
			'end_divider' => array(
29
				'name'  => __( 'End Section', 'formidable' ),
30
				'switch_from' => 'divider',
31
			),
32
			'divider'   => __( 'Section', 'formidable' ),
33
			'break'     => __( 'Page Break', 'formidable' ),
34
			'file'      => __( 'File Upload', 'formidable' ),
35
			'rte'       => __( 'Rich Text', 'formidable' ),
36
			'number'    => __( 'Number', 'formidable' ),
37
			'phone'     => __( 'Phone Number', 'formidable' ),
38
			'date'      => __( 'Date', 'formidable' ),
39
			'time'      => __( 'Time', 'formidable' ),
40
			'image'     => __( 'Image URL', 'formidable' ),
41
			'scale'     => __( 'Scale', 'formidable' ),
42
			'data'      => __( 'Dynamic Field', 'formidable' ),
43
			'lookup'    => __( 'Lookup', 'formidable' ),
44
			'form'      => __( 'Embed Form', 'formidable' ),
45
			'hidden'    => __( 'Hidden Field', 'formidable' ),
46
			'user_id'   => __( 'User ID (hidden)', 'formidable' ),
47
			'password'  => __( 'Password', 'formidable' ),
48
			'html'      => __( 'HTML', 'formidable' ),
49
			'tag'       => __( 'Tags', 'formidable' ),
50
			'credit_card' => __( 'Credit Card', 'formidable' ),
51
			'address'   => __( 'Address', 'formidable' ),
52
		));
53
	}
54
55
    public static function create( $values, $return = true ) {
56
        global $wpdb, $frm_duplicate_ids;
57
58
        $new_values = array();
59
        $key = isset($values['field_key']) ? $values['field_key'] : $values['name'];
60
		$new_values['field_key'] = FrmAppHelper::get_unique_key( $key, $wpdb->prefix . 'frm_fields', 'field_key' );
61
62
		foreach ( array( 'name', 'description', 'type', 'default_value' ) as $col ) {
63
			$new_values[ $col ] = $values[ $col ];
64
        }
65
66
        $new_values['options'] = $values['options'];
67
68
        $new_values['field_order'] = isset($values['field_order']) ? (int) $values['field_order'] : null;
69
        $new_values['required'] = isset($values['required']) ? (int) $values['required'] : 0;
70
        $new_values['form_id'] = isset($values['form_id']) ? (int) $values['form_id'] : null;
71
        $new_values['field_options'] = $values['field_options'];
72
        $new_values['created_at'] = current_time('mysql', 1);
73
74
		if ( isset( $values['id'] ) ) {
75
			$frm_duplicate_ids[ $values['field_key'] ] = $new_values['field_key'];
76
            $new_values = apply_filters('frm_duplicated_field', $new_values);
77
        }
78
79
		foreach ( $new_values as $k => $v ) {
80
            if ( is_array( $v ) ) {
81
				$new_values[ $k ] = serialize( $v );
82
			}
83
            unset( $k, $v );
84
        }
85
86
        //if(isset($values['id']) and is_numeric($values['id']))
87
        //    $new_values['id'] = $values['id'];
88
89
		$query_results = $wpdb->insert( $wpdb->prefix . 'frm_fields', $new_values );
90
		$new_id = 0;
91
		if ( $query_results ) {
92
			self::delete_form_transient( $new_values['form_id'] );
93
			$new_id = $wpdb->insert_id;
94
		}
95
96
		if ( ! $return ) {
97
			return false;
98
		}
99
100
		if ( $query_results ) {
101
			if ( isset( $values['id'] ) ) {
102
				$frm_duplicate_ids[ $values['id'] ] = $new_id;
103
			}
104
			return $new_id;
105
		} else {
106
			return false;
107
		}
108
    }
109
110
    public static function duplicate( $old_form_id, $form_id, $copy_keys = false, $blog_id = false ) {
111
        global $frm_duplicate_ids;
112
113
		$where = array(
114
			array(
115
				'or' => 1,
116
				'fi.form_id' => $old_form_id,
117
				'fr.parent_form_id' => $old_form_id,
118
			),
119
		);
120
		$fields = self::getAll( $where, 'field_order', '', $blog_id );
121
122
        foreach ( (array) $fields as $field ) {
123
			$new_key = $copy_keys ? $field->field_key : '';
124
            if ( $copy_keys && substr($field->field_key, -1) == 2 ) {
125
                $new_key = rtrim($new_key, 2);
126
            }
127
128
            $values = array();
129
            FrmFieldsHelper::fill_field( $values, $field, $form_id, $new_key );
130
131
			// If this is a repeating section, create new form
132
			if ( self::is_repeating_field( $field ) ) {
133
				// create the repeatable form
134
				$new_repeat_form_id = apply_filters( 'frm_create_repeat_form', 0, array(
135
					'parent_form_id' => $form_id,
136
					'field_name'     => $field->name,
137
				) );
138
139
				// Save old form_select
140
				$old_repeat_form_id = $field->field_options['form_select'];
141
142
				// Update form_select for repeating field
143
				$values['field_options']['form_select'] = $new_repeat_form_id;
144
			}
145
146
			// If this is a field inside of a repeating section, associate it with the correct form
147
			if ( $field->form_id != $old_form_id && isset( $old_repeat_form_id ) && isset( $new_repeat_form_id ) && $field->form_id == $old_repeat_form_id ) {
148
				$values['form_id'] = $new_repeat_form_id;
149
			}
150
151
            $values = apply_filters('frm_duplicated_field', $values);
152
            $new_id = self::create($values);
153
            $frm_duplicate_ids[ $field->id ] = $new_id;
154
            $frm_duplicate_ids[ $field->field_key ] = $new_id;
155
            unset($field);
156
        }
157
    }
158
159
	public static function update( $id, $values ) {
160
        global $wpdb;
161
162
		$id = absint( $id );
163
164
		if ( isset( $values['field_key'] ) ) {
165
			$values['field_key'] = FrmAppHelper::get_unique_key( $values['field_key'], $wpdb->prefix . 'frm_fields', 'field_key', $id );
166
		}
167
168
        if ( isset($values['required']) ) {
169
            $values['required'] = (int) $values['required'];
170
        }
171
172
		self::preserve_format_option_backslashes( $values );
173
174
		if ( isset( $values['type'] ) ) {
175
			$values = apply_filters( 'frm_clean_' . $values['type'] . '_field_options_before_update', $values );
176
177
			if ( $values['type'] == 'hidden' && isset( $values['field_options'] ) && isset( $values['field_options']['clear_on_focus'] ) ) {
178
				// don't keep the old placeholder setting for hidden fields
179
				$values['field_options']['clear_on_focus'] = 0;
180
			}
181
		}
182
183
		// serialize array values
184
		foreach ( array( 'default_value', 'field_options', 'options' ) as $opt ) {
185
			if ( isset( $values[ $opt ] ) && is_array( $values[ $opt ] ) ) {
186
				$values[ $opt ] = serialize( $values[ $opt ] );
187
			}
188
		}
189
190
		$query_results = $wpdb->update( $wpdb->prefix . 'frm_fields', $values, array( 'id' => $id ) );
191
192
        $form_id = 0;
193
		if ( isset( $values['form_id'] ) ) {
194
            $form_id = absint( $values['form_id'] );
195
		} else {
196
            $field = self::getOne($id);
197
            if ( $field ) {
198
                $form_id = $field->form_id;
199
            }
200
            unset($field);
201
        }
202
        unset($values);
203
204
		if ( $query_results ) {
205
            wp_cache_delete( $id, 'frm_field' );
206
            if ( $form_id ) {
207
                self::delete_form_transient( $form_id );
208
            }
209
        }
210
211
        return $query_results;
212
    }
213
214
	/**
215
	* Keep backslashes in the phone format option
216
	*
217
	* @since 2.0.8
218
	* @param $values array - pass by reference
219
	*/
220
	private static function preserve_format_option_backslashes( &$values ) {
221
		if ( isset( $values['field_options']['format'] ) ) {
222
			$values['field_options']['format'] = FrmAppHelper::preserve_backslashes( $values['field_options']['format'] );
223
		}
224
	}
225
226
    public static function destroy( $id ) {
227
		global $wpdb;
228
229
		do_action( 'frm_before_destroy_field', $id );
230
231
		wp_cache_delete( $id, 'frm_field' );
232
		$field = self::getOne( $id );
233
		if ( ! $field ) {
234
			return false;
235
		}
236
237
		self::delete_form_transient( $field->form_id );
238
239
		$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_item_metas WHERE field_id=%d', $id ) );
240
		return $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_fields WHERE id=%d', $id ) );
241
    }
242
243
	public static function delete_form_transient( $form_id ) {
244
		$form_id = absint( $form_id );
245
		delete_transient( 'frm_form_fields_' . $form_id . 'excludeinclude' );
246
		delete_transient( 'frm_form_fields_' . $form_id . 'includeinclude' );
247
		delete_transient( 'frm_form_fields_' . $form_id . 'includeexclude' );
248
		delete_transient( 'frm_form_fields_' . $form_id . 'excludeexclude' );
249
250
		global $wpdb;
251
		$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s', '_transient_timeout_frm_form_fields_' . $form_id . 'ex%', '_transient_frm_form_fields_' . $form_id . 'ex%', '_transient_timeout_frm_form_fields_' . $form_id . 'in%', '_transient_frm_form_fields_' . $form_id . 'in%' ) );
252
253
		FrmDb::cache_delete_group( 'frm_field' );
254
255
        $form = FrmForm::getOne($form_id);
256
        if ( $form && $form->parent_form_id && $form->parent_form_id != $form_id ) {
257
            self::delete_form_transient( $form->parent_form_id );
258
        }
259
    }
260
261
	/**
262
	 * If $field is numeric, get the field object
263
	 */
264
	public static function maybe_get_field( &$field ) {
265
		if ( ! is_object( $field ) ) {
266
			$field = self::getOne( $field );
267
		}
268
	}
269
270
	public static function getOne( $id ) {
0 ignored issues
show
Coding Style introduced by
The function name getOne is in camel caps, but expected get_one instead as per the coding standard.
Loading history...
271
		if ( empty( $id ) ) {
272
			return null;
273
		}
274
275
        global $wpdb;
276
277
        $where = is_numeric($id) ? 'id=%d' : 'field_key=%s';
278
		$query = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'frm_fields WHERE ' . $where, $id );
279
280
        $results = FrmDb::check_cache( $id, 'frm_field', $query, 'get_row', 0 );
281
282
        if ( empty($results) ) {
283
            return $results;
284
        }
285
286 View Code Duplication
        if ( is_numeric($id) ) {
287
			FrmDb::set_cache( $results->field_key, $results, 'frm_field' );
288
        } else if ( $results ) {
289
			FrmDb::set_cache( $results->id, $results, 'frm_field' );
290
        }
291
292
		self::prepare_options( $results );
293
294
        return stripslashes_deep($results);
295
    }
296
297
    /**
298
     * Get the field type by key or id
299
     * @param int|string The field id or key
300
	 * @param mixed $col The name of the column in the fields database table
301
     */
302
    public static function get_type( $id, $col = 'type' ) {
303
        $field = FrmDb::check_cache( $id, 'frm_field' );
304
        if ( $field ) {
305
            $type = $field->{$col};
306
        } else {
307
			$where = array(
308
				'or'        => 1,
309
				'id'        => $id,
310
				'field_key' => $id,
311
			);
312
			$type = FrmDb::get_var( 'frm_fields', $where, $col );
313
        }
314
315
        return $type;
316
    }
317
318
	public static function get_all_types_in_form( $form_id, $type, $limit = '', $inc_sub = 'exclude' ) {
319
        if ( ! $form_id ) {
320
            return array();
321
        }
322
323
		$results = self::get_fields_from_transients( $form_id, array(
324
			'inc_embed'  => $inc_sub,
325
			'inc_repeat' => $inc_sub,
326
		) );
327
		if ( ! empty( $results ) ) {
328
            $fields = array();
329
            $count = 0;
330
            foreach ( $results as $result ) {
331
                if ( $type != $result->type ) {
332
                    continue;
333
                }
334
335
				$fields[ $result->id ] = $result;
336
                $count++;
337
                if ( $limit == 1 ) {
338
                    $fields = $result;
339
                    break;
340
                }
341
342
                if ( ! empty($limit) && $count >= $limit ) {
343
                    break;
344
                }
345
346
                unset($result);
347
            }
348
            return stripslashes_deep($fields);
349
        }
350
351
        self::$use_cache = false;
352
353
		$where = array(
354
			'fi.form_id' => (int) $form_id,
355
			'fi.type'    => $type,
356
		);
357
		self::maybe_include_repeating_fields( $inc_sub, $where );
358
		$results = self::getAll( $where, 'field_order', $limit );
359
        self::$use_cache = true;
360
        self::include_sub_fields($results, $inc_sub, $type);
361
362
        return $results;
363
    }
364
365
	public static function get_all_for_form( $form_id, $limit = '', $inc_embed = 'exclude', $inc_repeat = 'include' ) {
366
        if ( ! (int) $form_id ) {
367
            return array();
368
        }
369
370
		$results = self::get_fields_from_transients( $form_id, array(
371
			'inc_embed'  => $inc_embed,
372
			'inc_repeat' => $inc_repeat,
373
		) );
374
		if ( ! empty( $results ) ) {
375
            if ( empty($limit) ) {
376
				return $results;
377
            }
378
379
            $fields = array();
380
            $count = 0;
381
            foreach ( $results as $result ) {
382
				$fields[ $result->id ] = $result;
383
                if ( ! empty($limit) && $count >= $limit ) {
384
                    break;
385
                }
386
            }
387
388
			return $fields;
389
        }
390
391
        self::$use_cache = false;
392
393
		$where = array( 'fi.form_id' => absint( $form_id ) );
394
		self::maybe_include_repeating_fields( $inc_repeat, $where );
395
		$results = self::getAll( $where, 'field_order', $limit );
396
397
        self::$use_cache = true;
398
399
		self::include_sub_fields( $results, $inc_embed, 'all' );
400
401
        if ( empty($limit) ) {
402
			self::set_field_transient( $results, $form_id, 0, array(
403
				'inc_embed'  => $inc_embed,
404
				'inc_repeat' => $inc_repeat,
405
			) );
406
        }
407
408
		return $results;
409
    }
410
411
	/**
412
	* If repeating fields should be included, adjust $where accordingly
413
	*
414
	* @param string $inc_repeat
415
	* @param array $where - pass by reference
416
	*/
417
	private static function maybe_include_repeating_fields( $inc_repeat, &$where ) {
418
		if ( $inc_repeat == 'include' ) {
419
			$form_id = $where['fi.form_id'];
420
			$where[] = array(
421
				'or'         => 1,
422
				'fi.form_id' => $form_id,
423
				'fr.parent_form_id' => $form_id,
424
			);
425
			unset( $where['fi.form_id'] );
426
		}
427
	}
428
429
	public static function include_sub_fields( &$results, $inc_embed, $type = 'all' ) {
430
		if ( 'include' != $inc_embed || empty( $results ) ) {
431
            return;
432
        }
433
434
        $form_fields = $results;
435
		$index_offset = 1;
436
        foreach ( $form_fields as $k => $field ) {
437
            if ( 'form' != $field->type || ! isset($field->field_options['form_select']) ) {
438
                continue;
439
            }
440
441
            if ( $type == 'all' ) {
442
                $sub_fields = self::get_all_for_form( $field->field_options['form_select'] );
443
            } else {
444
                $sub_fields = self::get_all_types_in_form($field->form_id, $type);
445
            }
446
447
            if ( ! empty($sub_fields) ) {
448
				$index = $k + $index_offset;
449
				$index_offset += count( $sub_fields );
450
				array_splice($results, $index, 0, $sub_fields);
451
            }
452
            unset($field, $sub_fields);
453
        }
454
    }
455
456
	public static function getAll( $where = array(), $order_by = '', $limit = '', $blog_id = false ) {
0 ignored issues
show
Coding Style introduced by
The function name getAll is in camel caps, but expected get_all instead as per the coding standard.
Loading history...
457
		$cache_key = maybe_serialize( $where ) . $order_by . 'l' . $limit . 'b' . $blog_id;
458
        if ( self::$use_cache ) {
459
            // make sure old cache doesn't get saved as a transient
460
            $results = wp_cache_get($cache_key, 'frm_field');
461
            if ( false !== $results ) {
462
                return stripslashes_deep($results);
463
            }
464
        }
465
466
        global $wpdb;
467
468
        if ( $blog_id && is_multisite() ) {
469
            global $wpmuBaseTablePrefix;
470
            if ( $wpmuBaseTablePrefix ) {
471
				$prefix = $wpmuBaseTablePrefix . $blog_id . '_';
472
            } else {
473
                $prefix = $wpdb->get_blog_prefix( $blog_id );
474
            }
475
476
			$table_name = $prefix . 'frm_fields';
477
			$form_table_name = $prefix . 'frm_forms';
478
		} else {
479
			$table_name = $wpdb->prefix . 'frm_fields';
480
			$form_table_name = $wpdb->prefix . 'frm_forms';
481
        }
482
483
		if ( ! empty( $order_by ) && strpos( $order_by, 'ORDER BY' ) === false ) {
484
			$order_by = ' ORDER BY ' . $order_by;
485
		}
486
487
		$limit = FrmDb::esc_limit( $limit );
488
489
        $query = "SELECT fi.*, fr.name as form_name  FROM {$table_name} fi LEFT OUTER JOIN {$form_table_name} fr ON fi.form_id=fr.id";
490
        $query_type = ( $limit == ' LIMIT 1' || $limit == 1 ) ? 'row' : 'results';
491
492
		if ( is_array( $where ) ) {
493
			$args = array(
494
				'order_by' => $order_by,
495
				'limit'    => $limit,
496
			);
497
			$results = FrmDb::get_var( $table_name . ' fi LEFT OUTER JOIN ' . $form_table_name . ' fr ON fi.form_id=fr.id', $where, 'fi.*, fr.name as form_name', $args, '', $query_type );
498
		} else {
499
			// if the query is not an array, then it has already been prepared
500
			$query .= FrmDb::prepend_and_or_where(' WHERE ', $where ) . $order_by . $limit;
501
502
			$function_name = ( $query_type == 'row' ) ? 'get_row' : 'get_results';
503
			$results = $wpdb->$function_name( $query );
504
        }
505
        unset( $where );
506
507
		self::format_field_results( $results );
508
509
		FrmDb::set_cache( $cache_key, $results, 'frm_field' );
510
511
		return stripslashes_deep( $results );
512
	}
513
514
	/**
515
	 * @since 2.0.8
516
	 */
517
	private static function format_field_results( &$results ) {
518
		if ( is_array( $results ) ) {
519
			foreach ( $results as $r_key => $result ) {
520
				FrmDb::set_cache( $result->id, $result, 'frm_field' );
521
				FrmDb::set_cache( $result->field_key, $result, 'frm_field' );
522
523
				$results[ $r_key ]->field_options = maybe_unserialize( $result->field_options );
524
				$results[ $r_key ]->options = maybe_unserialize( $result->options );
525
				$results[ $r_key ]->default_value = maybe_unserialize( $result->default_value );
526
527
				unset( $r_key, $result );
528
			}
529 View Code Duplication
		} else if ( $results ) {
530
			FrmDb::set_cache( $results->id, $results, 'frm_field' );
531
			FrmDb::set_cache( $results->field_key, $results, 'frm_field' );
532
533
			self::prepare_options( $results );
534
		}
535
	}
536
537
	/**
538
	 * Unserialize all the serialized field data
539
	 * @since 2.0
540
	 */
541
	private static function prepare_options( &$results ) {
542
		$results->field_options = maybe_unserialize( $results->field_options );
543
544
		$results->options = maybe_unserialize($results->options);
545
		$results->default_value = maybe_unserialize($results->default_value);
546
	}
547
548
	/**
549
	 * If a form has too many fields, thay won't all save into a single transient.
550
	 * We'll break them into groups of 200
551
	 * @since 2.0.1
552
	 */
553
	private static function get_fields_from_transients( $form_id, $args ) {
554
		$fields = array();
555
		self::get_next_transient( $fields, 'frm_form_fields_' . $form_id . $args['inc_embed'] . $args['inc_repeat'] );
556
		return $fields;
557
	}
558
559
	/**
560
	 * Called by get_fields_from_transients
561
	 * @since 2.0.1
562
	 */
563
	private static function get_next_transient( &$fields, $base_name, $next = 0 ) {
564
		$name = $next ? $base_name . $next : $base_name;
565
		$next_fields = get_transient( $name );
566
567
		if ( $next_fields ) {
568
			$fields = array_merge( $fields, $next_fields );
569
570
			if ( count( $next_fields ) >= self::$transient_size ) {
571
				// if this transient is full, check for another
572
				$next++;
573
				self::get_next_transient( $fields, $base_name, $next );
574
			}
575
		}
576
	}
577
578
	/**
579
	 * Save the transients in chunks for large forms
580
	 * @since 2.0.1
581
	 */
582
	private static function set_field_transient( &$fields, $form_id, $next = 0, $args = array() ) {
583
		$base_name = 'frm_form_fields_' . $form_id . $args['inc_embed'] . $args['inc_repeat'];
584
		$field_chunks = array_chunk( $fields, self::$transient_size );
585
586
		foreach ( $field_chunks as $field ) {
587
			$name = $next ? $base_name . $next : $base_name;
588
			$set = set_transient( $name, $field, 60 * 60 * 6 );
589
			if ( ! $set ) {
590
				// the transient didn't save
591
				if ( $name != $base_name ) {
592
					// if the first saved an others fail, this will show an incmoplete form
593
					self::delete_form_transient( $form_id );
594
				}
595
				return;
596
			}
597
598
			$next++;
599
		}
600
	}
601
602
	public static function is_no_save_field( $type ) {
603
		return in_array( $type, self::no_save_fields() );
604
	}
605
606
	public static function no_save_fields() {
607
		return array( 'divider', 'end_divider', 'captcha', 'break', 'html', 'form' );
608
	}
609
610
	/**
611
	 * Check if this field can hold an array of values
612
	 *
613
	 * @since 2.0.9
614
	 *
615
	 * @param array|object $field
616
	 * @return boolean
617
	 */
618
	public static function is_field_with_multiple_values( $field ) {
619
		if ( ! $field ) {
620
			return false;
621
		}
622
623
		$field_type = is_array( $field ) ? $field['type'] : $field->type;
624
		$data_type = self::get_option( $field, 'data_type' );
625
		$original_type = self::get_option( $field, 'original_type' );
626
627
		if ( ! empty( $original_type ) && $original_type != $field_type ) {
628
			$field_type = $original_type; // check the original type for arrays
629
		}
630
631
		$is_multi_value_field = (
632
			$field_type == 'checkbox' ||
633
			$field_type == 'address' ||
634
			( $field_type == 'data' && $data_type == 'checkbox' ) ||
635
			( $field_type == 'lookup' && $data_type == 'checkbox' ) ||
636
			self::is_multiple_select( $field )
637
		);
638
639
		return $is_multi_value_field;
640
	}
641
642
	/**
643
	 * Check if this is a multiselect dropdown field
644
	 *
645
	 * @since 2.0.9
646
	 * @return boolean
647
	 */
648
	public static function is_multiple_select( $field ) {
649
		$field_type = is_array( $field ) ? $field['type'] : $field->type;
650
		$data_type = self::get_option( $field, 'data_type' );
651
652
		return self::is_option_true( $field, 'multiple' ) && ( ( $field_type == 'select' || ( $field_type == 'data' && $data_type == 'select' ) ) );
653
	}
654
655
	/**
656
	 * Check if a field is read only. Read only can be set in the field options,
657
	 * but disabled with the shortcode options
658
	 *
659
	 * @since 2.0.9
660
	 */
661
	public static function is_read_only( $field ) {
662
		global $frm_vars;
663
		return ( self::is_option_true( $field, 'read_only' ) && ( ! isset( $frm_vars['readonly'] ) || $frm_vars['readonly'] != 'disabled' ) );
664
	}
665
666
	/**
667
	 * @since 2.0.9
668
	 */
669
	public static function is_required( $field ) {
670
		$required = ( $field['required'] != '0' );
671
		$required = apply_filters( 'frm_is_field_required', $required, $field );
672
		return $required;
673
	}
674
675
	/**
676
	 * @since 2.0.9
677
	 */
678
	public static function is_option_true( $field, $option ) {
679
		if ( is_array( $field ) ) {
680
			return self::is_option_true_in_array( $field, $option );
681
		} else {
682
			return self::is_option_true_in_object( $field, $option );
683
		}
684
	}
685
686
	/**
687
	 * @since 2.0.9
688
	 */
689
	public static function is_option_empty( $field, $option ) {
690
		if ( is_array( $field ) ) {
691
			return self::is_option_empty_in_array( $field, $option );
692
		} else {
693
			return self::is_option_empty_in_object( $field, $option );
694
		}
695
	}
696
697
	public static function is_option_true_in_array( $field, $option ) {
698
		return isset( $field[ $option ] ) && $field[ $option ];
699
	}
700
701
	public static function is_option_true_in_object( $field, $option ) {
702
		return isset( $field->field_options[ $option ] ) && $field->field_options[ $option ];
703
	}
704
705
	public static function is_option_empty_in_array( $field, $option ) {
706
		return ! isset( $field[ $option ] ) || empty( $field[ $option ] );
707
	}
708
709
	public static function is_option_empty_in_object( $field, $option ) {
710
		return ! isset( $field->field_options[ $option ] ) || empty( $field->field_options[ $option ] );
711
	}
712
713
	public static function is_option_value_in_object( $field, $option ) {
714
		return isset( $field->field_options[ $option ] ) && $field->field_options[ $option ] != '';
715
	}
716
717
	/**
718
	 * @since 2.0.18
719
	 */
720
	public static function get_option( $field, $option ) {
721
		if ( is_array( $field ) ) {
722
			$option = self::get_option_in_array( $field, $option );
723
		} else {
724
			$option = self::get_option_in_object( $field, $option );
725
		}
726
		return $option;
727
	}
728
729
	public static function get_option_in_array( $field, $option ) {
730
		return isset( $field[ $option ] ) ? $field[ $option ] : '';
731
	}
732
733
	public static function get_option_in_object( $field, $option ) {
734
		return isset( $field->field_options[ $option ] ) ? $field->field_options[ $option ] : '';
735
	}
736
737
	/**
738
	* @since 2.0.09
739
	*/
740
	public static function is_repeating_field( $field ) {
741
		if ( is_array( $field ) ) {
742
			$is_repeating_field = ( 'divider' == $field['type'] );
743
		} else {
744
			$is_repeating_field = ( 'divider' == $field->type );
745
		}
746
		return ( $is_repeating_field && self::is_option_true( $field, 'repeat' ) );
747
	}
748
749
    /**
750
     * @param string $key
751
     * @return int field id
752
     */
753
	public static function get_id_by_key( $key ) {
754
        $id = FrmDb::get_var( 'frm_fields', array( 'field_key' => sanitize_title( $key ) ) );
755
        return $id;
756
    }
757
758
	/**
759
	 * @param string $id
760
	 * @return string
761
	 */
762
	public static function get_key_by_id( $id ) {
763
		return FrmDb::get_var( 'frm_fields', array( 'id' => $id ), 'field_key' );
764
	}
765
}
766