Completed
Push — master ( d6a0ab...fe76d8 )
by Stephanie
03:28
created

FrmForm::get_admin_params()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 6
nop 1
dl 0
loc 27
rs 9.1768
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 FrmForm {
7
8
    /**
9
     * @return int|boolean id on success or false on failure
10
     */
11
    public static function create( $values ) {
12
        global $wpdb;
13
14
		$new_values = array(
15
			'form_key'      => FrmAppHelper::get_unique_key( $values['form_key'], $wpdb->prefix . 'frm_forms', 'form_key' ),
16
			'name'          => $values['name'],
17
			'description'   => $values['description'],
18
			'status'        => isset( $values['status'] ) ? $values['status'] : 'draft',
19
			'logged_in'     => isset( $values['logged_in'] ) ? $values['logged_in'] : 0,
20
			'is_template'   => isset( $values['is_template'] ) ? (int) $values['is_template'] : 0,
21
			'parent_form_id' => isset( $values['parent_form_id'] ) ? absint( $values['parent_form_id'] ) : 0,
22
			'editable'      => isset( $values['editable'] ) ? (int) $values['editable'] : 0,
23
			'default_template' => isset( $values['default_template'] ) ? (int) $values['default_template'] : 0,
24
			'created_at'    => isset( $values['created_at'] ) ? $values['created_at'] : current_time( 'mysql', 1 ),
25
		);
26
27
		$options = isset( $values['options'] ) ? (array) $values['options'] : array();
28
		FrmFormsHelper::fill_form_options( $options, $values );
29
30
		$options['before_html'] = isset( $values['options']['before_html'] ) ? $values['options']['before_html'] : FrmFormsHelper::get_default_html( 'before' );
31
		$options['after_html'] = isset( $values['options']['after_html'] ) ? $values['options']['after_html'] : FrmFormsHelper::get_default_html( 'after' );
32
		$options['submit_html'] = isset( $values['options']['submit_html'] ) ? $values['options']['submit_html'] : FrmFormsHelper::get_default_html( 'submit' );
33
34
		$options = apply_filters( 'frm_form_options_before_update', $options, $values );
35
		$new_values['options'] = serialize( $options );
36
37
        //if(isset($values['id']) && is_numeric($values['id']))
38
        //    $new_values['id'] = $values['id'];
39
40
		$wpdb->insert( $wpdb->prefix . 'frm_forms', $new_values );
41
42
        $id = $wpdb->insert_id;
43
44
		// Clear form caching
45
		self::clear_form_cache();
46
47
        return $id;
48
    }
49
50
    /**
51
     * @return int|boolean ID on success or false on failure
52
     */
53
    public static function duplicate( $id, $template = false, $copy_keys = false, $blog_id = false ) {
54
        global $wpdb;
55
56
        $values = self::getOne( $id, $blog_id );
57
        if ( ! $values ) {
58
            return false;
59
        }
60
61
        $new_key = $copy_keys ? $values->form_key : '';
62
63
        $new_values = array(
64
			'form_key'      => FrmAppHelper::get_unique_key( $new_key, $wpdb->prefix . 'frm_forms', 'form_key' ),
65
            'name'          => $values->name,
66
            'description'   => $values->description,
67
            'status'        => $template ? 'published' : 'draft',
68
            'logged_in'     => $values->logged_in ? $values->logged_in : 0,
69
            'editable'      => $values->editable ? $values->editable : 0,
70
			'created_at'    => current_time( 'mysql', 1 ),
71
            'is_template'   => $template ? 1 : 0,
72
        );
73
74
        if ( $blog_id ) {
75
            $new_values['status'] = 'published';
76
			$new_options = maybe_unserialize( $values->options );
77
			$new_options['email_to'] = get_option( 'admin_email' );
78
            $new_options['copy'] = false;
79
            $new_values['options'] = $new_options;
80
        } else {
81
            $new_values['options'] = $values->options;
82
        }
83
84
		if ( is_array( $new_values['options'] ) ) {
85
			$new_values['options'] = serialize( $new_values['options'] );
86
		}
87
88
		$query_results = $wpdb->insert( $wpdb->prefix . 'frm_forms', $new_values );
89
90
        if ( $query_results ) {
91
			// Clear form caching
92
			self::clear_form_cache();
93
94
            $form_id = $wpdb->insert_id;
95
			FrmField::duplicate( $id, $form_id, $copy_keys, $blog_id );
96
97
            // update form settings after fields are created
98
			do_action( 'frm_after_duplicate_form', $form_id, $new_values, array( 'old_id' => $id ) );
99
            return $form_id;
100
        }
101
102
        return false;
103
    }
104
105
	public static function after_duplicate( $form_id, $values ) {
106
		$new_opts = maybe_unserialize( $values['options'] );
107
		$values['options'] = $new_opts;
108
109
		if ( isset( $new_opts['success_msg'] ) ) {
110
			$new_opts['success_msg'] = FrmFieldsHelper::switch_field_ids( $new_opts['success_msg'] );
111
		}
112
113
		$new_opts = apply_filters( 'frm_after_duplicate_form_values', $new_opts, $form_id );
114
115
        if ( $new_opts != $values['options'] ) {
116
            global $wpdb;
117
			$wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => maybe_serialize( $new_opts ) ), array( 'id' => $form_id ) );
118
        }
119
    }
120
121
    /**
122
     * @return int|boolean
123
     */
124
    public static function update( $id, $values, $create_link = false ) {
125
        global $wpdb;
126
127
        if ( ! isset( $values['status'] ) && ( $create_link || isset( $values['options'] ) || isset( $values['item_meta'] ) || isset( $values['field_options'] ) ) ) {
128
            $values['status'] = 'published';
129
        }
130
131
		if ( isset( $values['form_key'] ) ) {
132
			$values['form_key'] = FrmAppHelper::get_unique_key( $values['form_key'], $wpdb->prefix . 'frm_forms', 'form_key', $id );
133
        }
134
135
		$form_fields = array( 'form_key', 'name', 'description', 'status', 'parent_form_id' );
136
137
		$new_values = self::set_update_options( array(), $values );
138
139
        foreach ( $values as $value_key => $value ) {
140
			if ( $value_key && in_array( $value_key, $form_fields ) ) {
141
				$new_values[ $value_key ] = $value;
142
            }
143
        }
144
145
        if ( isset( $values['new_status'] ) && ! empty( $values['new_status'] ) ) {
146
            $new_values['status'] = $values['new_status'];
147
        }
148
149
        if ( ! empty( $new_values ) ) {
150
			$query_results = $wpdb->update( $wpdb->prefix . 'frm_forms', $new_values, array( 'id' => $id ) );
151
            if ( $query_results ) {
152
				self::clear_form_cache();
153
            }
154
        } else {
155
            $query_results = true;
156
        }
157
		unset( $new_values );
158
159
		$values = self::update_fields( $id, $values );
160
161
		do_action( 'frm_update_form', $id, $values );
162
		do_action( 'frm_update_form_' . $id, $values );
163
164
        return $query_results;
165
    }
166
167
    /**
168
     * @return array
169
     */
170
	public static function set_update_options( $new_values, $values ) {
171
		if ( ! isset( $values['options'] ) ) {
172
            return $new_values;
173
        }
174
175
		$options = isset( $values['options'] ) ? (array) $values['options'] : array();
176
		FrmFormsHelper::fill_form_options( $options, $values );
177
178
		$options['custom_style'] = isset( $values['options']['custom_style'] ) ? $values['options']['custom_style'] : 0;
179
		$options['before_html'] = isset( $values['options']['before_html'] ) ? $values['options']['before_html'] : FrmFormsHelper::get_default_html( 'before' );
180
		$options['after_html'] = isset( $values['options']['after_html'] ) ? $values['options']['after_html'] : FrmFormsHelper::get_default_html( 'after' );
181
		$options['submit_html'] = ( isset( $values['options']['submit_html'] ) && '' !== $values['options']['submit_html'] ) ? $values['options']['submit_html'] : FrmFormsHelper::get_default_html( 'submit' );
182
183
		$options = apply_filters( 'frm_form_options_before_update', $options, $values );
184
		$new_values['options'] = serialize( $options );
185
186
		return $new_values;
187
    }
188
189
190
    /**
191
     * @return array
192
     */
193
	public static function update_fields( $id, $values ) {
194
195
		if ( ! isset( $values['item_meta'] ) && ! isset( $values['field_options'] ) ) {
196
            return $values;
197
        }
198
199
		$all_fields = FrmField::get_all_for_form( $id );
200
		if ( empty( $all_fields ) ) {
201
			return $values;
202
		}
203
204
		if ( ! isset( $values['item_meta'] ) ) {
205
			$values['item_meta'] = array();
206
		}
207
208
        $field_array = array();
209
        $existing_keys = array_keys( $values['item_meta'] );
210
        foreach ( $all_fields as $fid ) {
211
			if ( ! in_array( $fid->id, $existing_keys ) && ( isset( $values['frm_fields_submitted'] ) && in_array( $fid->id, $values['frm_fields_submitted'] ) ) || isset( $values['options'] ) ) {
212
				$values['item_meta'][ $fid->id ] = '';
213
            }
214
			$field_array[ $fid->id ] = $fid;
215
        }
216
		unset( $all_fields );
217
218
        foreach ( $values['item_meta'] as $field_id => $default_value ) {
219
			if ( isset( $field_array[ $field_id ] ) ) {
220
				$field = $field_array[ $field_id ];
221
            } else {
222
				$field = FrmField::getOne( $field_id );
223
            }
224
225
            if ( ! $field ) {
226
                continue;
227
            }
228
229
			$is_settings_page = ( isset( $values['options'] ) || isset( $values['field_options'][ 'custom_html_' . $field_id ] ) );
230
			if ( $is_settings_page ) {
231
				self::get_settings_page_html( $values, $field );
232
233
				if ( ! defined( 'WP_IMPORTING' ) ) {
234
					continue;
235
				}
236
			}
237
238
			//updating the form
239
			$update_options = FrmFieldsHelper::get_default_field_options_from_field( $field );
240
			unset( $update_options['custom_html'] ); // don't check for POST html
241
			$update_options = apply_filters( 'frm_field_options_to_update', $update_options );
242
243
			foreach ( $update_options as $opt => $default ) {
244
				$field->field_options[ $opt ] = isset( $values['field_options'][ $opt . '_' . $field_id ] ) ? $values['field_options'][ $opt . '_' . $field_id ] : $default;
245
				self::sanitize_field_opt( $opt, $field->field_options[ $opt ] );
246
            }
247
248
			$field->field_options = apply_filters( 'frm_update_field_options', $field->field_options, $field, $values );
249
			$default_value = maybe_serialize( $values['item_meta'][ $field_id ] );
250
251
			$new_field = array(
252
				'field_options' => $field->field_options,
253
				'default_value' => $default_value,
254
			);
255
256
			self::prepare_field_update_values( $field, $values, $new_field );
257
258
			FrmField::update( $field_id, $new_field );
259
260
			FrmField::delete_form_transient( $field->form_id );
261
        }
262
		self::clear_form_cache();
263
264
        return $values;
265
    }
266
267
	private static function sanitize_field_opt( $opt, &$value ) {
268
		if ( is_string( $value ) ) {
269
			if ( $opt === 'calc' ) {
270
				$value = strip_tags( $value );
271
			} else {
272
				$value = FrmAppHelper::kses( $value, 'all' );
273
			}
274
			$value = trim( $value );
275
		}
276
	}
277
278
	/**
279
	 * updating the settings page
280
	 */
281
	private static function get_settings_page_html( $values, &$field ) {
282
		if ( isset( $values['field_options'][ 'custom_html_' . $field->id ] ) ) {
283
			$prev_opts = array();
284
			$fallback_html = isset( $field->field_options['custom_html'] ) ? $field->field_options['custom_html'] : FrmFieldsHelper::get_default_html( $field->type );
285
			$field->field_options['custom_html'] = isset( $values['field_options'][ 'custom_html_' . $field->id ] ) ? $values['field_options'][ 'custom_html_' . $field->id ] : $fallback_html;
286
		} elseif ( $field->type == 'hidden' || $field->type == 'user_id' ) {
287
			$prev_opts = $field->field_options;
288
		}
289
290
		if ( isset( $prev_opts ) ) {
291
			$field->field_options = apply_filters( 'frm_update_form_field_options', $field->field_options, $field, $values );
292
			if ( $prev_opts != $field->field_options ) {
293
				FrmField::update( $field->id, array( 'field_options' => $field->field_options ) );
294
			}
295
		}
296
	}
297
298
	private static function prepare_field_update_values( $field, $values, &$new_field ) {
299
		$field_cols = array(
300
			'field_key'   => '',
301
			'required'    => false,
302
			'type'        => '',
303
			'description' => '',
304
			'options'     => '',
305
			'name'        => '',
306
		);
307
		foreach ( $field_cols as $col => $default ) {
308
			$default = ( $default === '' ) ? $field->{$col} : $default;
309
			$new_field[ $col ] = isset( $values['field_options'][ $col . '_' . $field->id ] ) ? $values['field_options'][ $col . '_' . $field->id ] : $default;
310
		}
311
	}
312
313
    /**
314
     * @param string $status
315
     * @return int|boolean
316
     */
317
	public static function set_status( $id, $status ) {
318
        if ( 'trash' == $status ) {
319
			return self::trash( $id );
320
        }
321
322
		$statuses  = array( 'published', 'draft', 'trash' );
323
        if ( ! in_array( $status, $statuses ) ) {
324
            return false;
325
        }
326
327
        global $wpdb;
328
329
		if ( is_array( $id ) ) {
330
			$where = array(
331
				'id' => $id,
332
				'parent_form_id' => $id,
333
				'or' => 1,
334
			);
335
			FrmDb::get_where_clause_and_values( $where );
336
			array_unshift( $where['values'], $status );
337
338
			$query_results = $wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->prefix . 'frm_forms SET status = %s ' . $where['where'], $where['values'] ) ); // WPCS: unprepared SQL ok.
339
        } else {
340
			$query_results = $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'status' => $status ), array( 'id' => $id ) );
341
			$wpdb->update( $wpdb->prefix . 'frm_forms', array( 'status' => $status ), array( 'parent_form_id' => $id ) );
342
        }
343
344
        if ( $query_results ) {
345
			self::clear_form_cache();
346
        }
347
348
        return $query_results;
349
    }
350
351
    /**
352
     * @return int|boolean
353
     */
354
	public static function trash( $id ) {
355
        if ( ! EMPTY_TRASH_DAYS ) {
356
            return self::destroy( $id );
357
        }
358
359
		$form = self::getOne( $id );
360
        if ( ! $form ) {
361
            return false;
362
        }
363
364
        $options = $form->options;
365
        $options['trash_time'] = time();
366
367
		global $wpdb;
368
		$query_results = $wpdb->update(
369
			$wpdb->prefix . 'frm_forms',
370
			array(
371
				'status'  => 'trash',
372
				'options' => serialize( $options ),
373
			),
374
			array(
375
				'id' => $id,
376
			)
377
		);
378
379
		$wpdb->update(
380
			$wpdb->prefix . 'frm_forms',
381
			array(
382
				'status'  => 'trash',
383
				'options' => serialize( $options ),
384
			),
385
			array(
386
				'parent_form_id' => $id,
387
			)
388
		);
389
390
        if ( $query_results ) {
391
			self::clear_form_cache();
392
        }
393
394
        return $query_results;
395
    }
396
397
    /**
398
     * @return int|boolean
399
     */
400
	public static function destroy( $id ) {
401
        global $wpdb;
402
403
		$form = self::getOne( $id );
404
        if ( ! $form ) {
405
            return false;
406
        }
407
		$id = $form->id;
408
409
        // Disconnect the entries from this form
410
		$entries = FrmDb::get_col( $wpdb->prefix . 'frm_items', array( 'form_id' => $id ) );
411
		foreach ( $entries as $entry_id ) {
0 ignored issues
show
Bug introduced by
The expression $entries 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...
412
			FrmEntry::destroy( $entry_id );
413
			unset( $entry_id );
414
		}
415
416
        // Disconnect the fields from this form
417
		$wpdb->query( $wpdb->prepare( 'DELETE fi FROM ' . $wpdb->prefix . 'frm_fields AS fi LEFT JOIN ' . $wpdb->prefix . 'frm_forms fr ON (fi.form_id = fr.id) WHERE fi.form_id=%d OR parent_form_id=%d', $id, $id ) );
418
419
		$query_results = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_forms WHERE id=%d OR parent_form_id=%d', $id, $id ) );
420
        if ( $query_results ) {
421
            // Delete all form actions linked to this form
422
            $action_control = FrmFormActionsController::get_form_actions( 'email' );
423
			$action_control->destroy( $id, 'all' );
424
425
			// Clear form caching
426
			self::clear_form_cache();
427
428
			do_action( 'frm_destroy_form', $id );
429
			do_action( 'frm_destroy_form_' . $id );
430
        }
431
432
        return $query_results;
433
    }
434
435
	/**
436
	 * Delete trashed forms based on how long they have been trashed
437
	 * @return int The number of forms deleted
438
	 */
439
	public static function scheduled_delete( $delete_timestamp = '' ) {
440
		global $wpdb;
441
442
		$trash_forms = FrmDb::get_results( $wpdb->prefix . 'frm_forms', array( 'status' => 'trash' ), 'id, options' );
443
444
		if ( ! $trash_forms ) {
445
			return;
446
		}
447
448
		if ( empty( $delete_timestamp ) ) {
449
			$delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
450
		}
451
452
		$count = 0;
453
		foreach ( $trash_forms as $form ) {
0 ignored issues
show
Bug introduced by
The expression $trash_forms of type array|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...
454
			$form->options = maybe_unserialize( $form->options );
455
			if ( ! isset( $form->options['trash_time'] ) || $form->options['trash_time'] < $delete_timestamp ) {
456
				self::destroy( $form->id );
457
				$count++;
458
			}
459
460
			unset( $form );
461
		}
462
		return $count;
463
	}
464
465
    /**
466
     * @return string form name
467
     */
468
    public static function getName( $id ) {
0 ignored issues
show
Coding Style introduced by
The function name getName is in camel caps, but expected get_name instead as per the coding standard.
Loading history...
469
		$form = FrmDb::check_cache( $id, 'frm_form' );
470
        if ( $form ) {
471
			$r = stripslashes( $form->name );
472
            return $r;
473
        }
474
475
        $query_key = is_numeric( $id ) ? 'id' : 'form_key';
476
        $r = FrmDb::get_var( 'frm_forms', array( $query_key => $id ), 'name' );
477
		$r = stripslashes( $r );
478
479
        return $r;
480
    }
481
482
    /**
483
	 * @since 3.0
484
     * @param string $key
485
     * @return int form id
486
     */
487
	public static function get_id_by_key( $key ) {
488
		return (int) FrmDb::get_var( 'frm_forms', array( 'form_key' => sanitize_title( $key ) ) );
489
    }
490
491
	/**
492
	 * @deprecated 3.0
493
	 * @codeCoverageIgnore
494
	 *
495
     * @param string $key
496
     * @return int form id
497
     */
498
	public static function getIdByKey( $key ) {
0 ignored issues
show
Coding Style introduced by
The function name getIdByKey is in camel caps, but expected get_id_by_key instead as per the coding standard.
Loading history...
499
		_deprecated_function( __METHOD__, '3.0', 'FrmForm::get_id_by_key' );
500
		return self::get_id_by_key( $key );
501
    }
502
503
    /**
504
	 * @since 3.0
505
     * @param int $id
506
     * @return string form key
507
     */
508
	public static function get_key_by_id( $id ) {
509
        $id = (int) $id;
510
		$cache = FrmDb::check_cache( $id, 'frm_form' );
511
        if ( $cache ) {
512
            return $cache->form_key;
513
        }
514
515
        $key = FrmDb::get_var( 'frm_forms', array( 'id' => $id ), 'form_key' );
516
517
        return $key;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $key; (array|null|string|object) is incompatible with the return type documented by FrmForm::get_key_by_id of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
518
    }
519
520
	/**
521
	 * @deprecated 3.0
522
	 * @codeCoverageIgnore
523
	 */
524
	public static function getKeyById( $id ) {
0 ignored issues
show
Coding Style introduced by
The function name getKeyById is in camel caps, but expected get_key_by_id instead as per the coding standard.
Loading history...
525
		_deprecated_function( __METHOD__, '3.0', 'FrmForm::get_key_by_id' );
526
		return self::get_key_by_id( $id );
527
	}
528
529
	/**
530
	 * If $form is numeric, get the form object
531
	 * @param object|int $form
532
	 * @since 2.0.9
533
	 */
534
	public static function maybe_get_form( &$form ) {
535
		if ( ! is_object( $form ) && ! is_array( $form ) && ! empty( $form ) ) {
536
			$form = self::getOne( $form );
537
		}
538
	}
539
540
    /**
541
     * @return object form
542
     */
543
    public static function getOne( $id, $blog_id = false ) {
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...
544
        global $wpdb;
545
546
        if ( $blog_id && is_multisite() ) {
547
            global $wpmuBaseTablePrefix;
548
			$prefix = $wpmuBaseTablePrefix ? $wpmuBaseTablePrefix . $blog_id . '_' : $wpdb->get_blog_prefix( $blog_id );
549
550
			$table_name = $prefix . 'frm_forms';
551
        } else {
552
			$table_name = $wpdb->prefix . 'frm_forms';
553
			$cache = wp_cache_get( $id, 'frm_form' );
554
            if ( $cache ) {
555
				if ( isset( $cache->options ) ) {
556
					$cache->options = maybe_unserialize( $cache->options );
557
                }
558
559
				return stripslashes_deep( $cache );
560
            }
561
        }
562
563
		if ( is_numeric( $id ) ) {
564
            $where = array( 'id' => $id );
565
        } else {
566
            $where = array( 'form_key' => $id );
567
        }
568
569
        $results = FrmDb::get_row( $table_name, $where );
570
571 View Code Duplication
		if ( isset( $results->options ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
572
			FrmDb::set_cache( $results->id, $results, 'frm_form' );
573
			$results->options = maybe_unserialize( $results->options );
574
        }
575
		return stripslashes_deep( $results );
576
    }
577
578
    /**
579
     * @return object|array of objects
580
     */
581
	public static function getAll( $where = array(), $order_by = '', $limit = '' ) {
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...
582
		if ( is_array( $where ) && ! empty( $where ) ) {
583
			if ( isset( $where['is_template'] ) && $where['is_template'] && ! isset( $where['status'] ) ) {
584
				// don't get trashed templates
585
				$where['status'] = array( null, '', 'published' );
586
			}
587
588
			$results = FrmDb::get_results( 'frm_forms', $where, '*', array(
589
				'order_by' => $order_by,
590
				'limit'    => $limit,
591
			) );
592
		} else {
593
			global $wpdb;
594
595
			// the query has already been prepared if this is not an array
596
			$query = 'SELECT * FROM ' . $wpdb->prefix . 'frm_forms' . FrmDb::prepend_and_or_where( ' WHERE ', $where ) . FrmDb::esc_order( $order_by ) . FrmDb::esc_limit( $limit );
597
			$results = $wpdb->get_results( $query ); // WPCS: unprepared SQL ok.
598
		}
599
600 View Code Duplication
		if ( $results ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
601
			foreach ( $results as $result ) {
602
				FrmDb::set_cache( $result->id, $result, 'frm_form' );
603
				$result->options = maybe_unserialize( $result->options );
604
			}
605
		}
606
607
		if ( $limit == ' LIMIT 1' || $limit == 1 ) {
608
			// return the first form object if we are only getting one form
609
			$results = reset( $results );
610
		}
611
612
		return stripslashes_deep( $results );
613
    }
614
615
	/**
616
	 * Get all published forms
617
	 * @since 2.0
618
	 * @return array of forms
619
	 */
620
	public static function get_published_forms( $query = array(), $limit = 999, $inc_children = 'exclude' ) {
621
		$query['is_template'] = 0;
622
		$query['status'] = array( null, '', 'published' );
623
		if ( $inc_children == 'exclude' ) {
624
			$query['parent_form_id'] = array( null, 0 );
625
		}
626
627
		$forms = self::getAll( $query, 'name', $limit );
628
		return $forms;
629
	}
630
631
    /**
632
     * @return int count of forms
633
     */
634
    public static function get_count() {
635
    	global $wpdb;
636
637
    	$cache_key = 'frm_form_counts';
638
639
    	$counts = wp_cache_get( $cache_key, 'frm_form' );
640
    	if ( false !== $counts ) {
641
    	    return $counts;
642
    	}
643
644
		$results = (array) FrmDb::get_results( 'frm_forms', array(
645
			'or' => 1,
646
			'parent_form_id' => null,
647
			'parent_form_id <' => 0,
648
		), 'status, is_template' );
649
650
		$statuses = array( 'published', 'draft', 'template', 'trash' );
651
    	$counts = array_fill_keys( $statuses, 0 );
652
653
    	foreach ( $results as $row ) {
654
            if ( 'trash' != $row->status ) {
655
    	        if ( $row->is_template ) {
656
					$counts['template']++;
657
    	        } else {
658
					$counts['published']++;
659
    	        }
660
    	    } else {
661
				$counts['trash']++;
662
        	}
663
664
    	    if ( 'draft' == $row->status ) {
665
				$counts['draft']++;
666
    	    }
667
668
			unset( $row );
669
    	}
670
671
    	$counts = (object) $counts;
672
		FrmDb::set_cache( $cache_key, $counts, 'frm_form' );
673
674
    	return $counts;
675
    }
676
677
	/**
678
	 * Clear form caching
679
	 * Called when a form is created, updated, duplicated, or deleted
680
	 * or when the form status is changed
681
	 *
682
	 * @since 2.0.4
683
	 */
684
	public static function clear_form_cache() {
685
		FrmDb::cache_delete_group( 'frm_form' );
686
	}
687
688
    /**
689
     * @return array of errors
690
     */
691
	public static function validate( $values ) {
692
        $errors = array();
693
694
		return apply_filters( 'frm_validate_form', $errors, $values );
695
    }
696
697
	public static function get_params( $form = null ) {
698
		global $frm_vars;
699
700
		if ( ! $form ) {
701
			$form = self::getAll( array(), 'name', 1 );
702
		} else {
703
			self::maybe_get_form( $form );
704
		}
705
706
		if ( isset( $frm_vars['form_params'] ) && is_array( $frm_vars['form_params'] ) && isset( $frm_vars['form_params'][ $form->id ] ) ) {
707
			return $frm_vars['form_params'][ $form->id ];
708
		}
709
710
		$action_var = isset( $_REQUEST['frm_action'] ) ? 'frm_action' : 'action'; // WPCS: CSRF ok.
711
		$action = apply_filters( 'frm_show_new_entry_page', FrmAppHelper::get_param( $action_var, 'new', 'get', 'sanitize_title' ), $form );
712
713
		$default_values = array(
714
			'id'        => '',
715
			'form_name' => '',
716
			'paged'     => 1,
717
			'form'      => $form->id,
718
			'form_id'   => $form->id,
719
			'field_id'  => '',
720
			'search'    => '',
721
			'sort'      => '',
722
			'sdir'      => '',
723
			'action'    => $action,
724
		);
725
726
		$values = array();
727
		$values['posted_form_id'] = FrmAppHelper::get_param( 'form_id', '', 'get', 'absint' );
728
		if ( ! $values['posted_form_id'] ) {
729
			$values['posted_form_id'] = FrmAppHelper::get_param( 'form', '', 'get', 'absint' );
730
		}
731
732
		if ( $form->id == $values['posted_form_id'] ) {
733
			//if there are two forms on the same page, make sure not to submit both
734
			foreach ( $default_values as $var => $default ) {
735
				if ( $var == 'action' ) {
736
					$values[ $var ] = FrmAppHelper::get_param( $action_var, $default, 'get', 'sanitize_title' );
737
				} else {
738
					$values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
739
				}
740
				unset( $var, $default );
741
			}
742
		} else {
743
			foreach ( $default_values as $var => $default ) {
744
				$values[ $var ] = $default;
745
				unset( $var, $default );
746
			}
747
		}
748
749
		if ( in_array( $values['action'], array( 'create', 'update' ) ) && ( ! $_POST || ( ! isset( $_POST['action'] ) && ! isset( $_POST['frm_action'] ) ) ) ) { // WPCS: CSRF ok.
750
			$values['action'] = 'new';
751
		}
752
753
		return $values;
754
	}
755
756
	public static function list_page_params() {
757
		$values = array();
758
		$defaults = array(
759
			'template' => 0,
760
			'id'     => '',
761
			'paged'  => 1,
762
			'form'   => '',
763
			'search' => '',
764
			'sort'   => '',
765
			'sdir'   => '',
766
		);
767
		foreach ( $defaults as $var => $default ) {
768
			$values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
769
		}
770
771
		return $values;
772
	}
773
774
	public static function get_admin_params( $form = null ) {
775
		$form_id = $form;
776
		if ( $form === null ) {
777
			$form_id = FrmForm::get_current_form_id();
778
		} else if ( $form && is_object( $form ) ) {
779
			$form_id = $form->id;
780
		}
781
782
		$values = array();
783
		$defaults = array(
784
			'id'        => '',
785
			'form_name' => '',
786
			'paged'     => 1,
787
			'form'      => $form_id,
788
			'field_id'  => '',
789
			'search'    => '',
790
			'sort'      => '',
791
			'sdir'      => '',
792
			'fid'       => '',
793
			'keep_post' => '',
794
		);
795
		foreach ( $defaults as $var => $default ) {
796
			$values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
797
		}
798
799
		return $values;
800
	}
801
802
	public static function get_current_form_id( $default_form = 'none' ) {
803
		if ( 'first' == $default_form ) {
804
			$form = self::get_current_form();
805
		} else {
806
			$form = self::maybe_get_current_form();
807
		}
808
		$form_id = $form ? $form->id : 0;
809
810
		return $form_id;
811
	}
812
813
	public static function maybe_get_current_form( $form_id = 0 ) {
814
		global $frm_vars;
815
816
		if ( isset( $frm_vars['current_form'] ) && $frm_vars['current_form'] && ( ! $form_id || $form_id == $frm_vars['current_form']->id ) ) {
817
			return $frm_vars['current_form'];
818
		}
819
820
		$form_id = FrmAppHelper::get_param( 'form', $form_id, 'get', 'absint' );
821
		if ( $form_id ) {
822
			$form_id = self::set_current_form( $form_id );
823
		}
824
		return $form_id;
825
	}
826
827
	public static function get_current_form( $form_id = 0 ) {
828
		$form = self::maybe_get_current_form( $form_id );
829
		if ( is_numeric( $form ) ) {
830
			 $form = self::set_current_form( $form );
831
		}
832
		return $form;
833
	}
834
835
	public static function set_current_form( $form_id ) {
836
		global $frm_vars;
837
838
		$query = array();
839
		if ( $form_id ) {
840
			$query['id'] = $form_id;
841
		}
842
843
		$frm_vars['current_form'] = self::get_published_forms( $query, 1 );
844
845
		return $frm_vars['current_form'];
846
	}
847
848
	public static function is_form_loaded( $form, $this_load, $global_load ) {
849
		global $frm_vars;
850
		$small_form = new stdClass();
851
		foreach ( array( 'id', 'form_key', 'name' ) as $var ) {
852
			$small_form->{$var} = $form->{$var};
853
			unset( $var );
854
		}
855
856
		$frm_vars['forms_loaded'][] = $small_form;
857
858
		if ( $this_load && empty( $global_load ) ) {
859
			$global_load = true;
860
			$frm_vars['load_css'] = true;
861
		}
862
863
		return ( ( ! isset( $frm_vars['css_loaded'] ) || ! $frm_vars['css_loaded'] ) && $global_load );
864
	}
865
866
	public static function show_submit( $form ) {
867
		$show = ( ! $form->is_template && $form->status == 'published' && ! FrmAppHelper::is_admin() );
868
		$show = apply_filters( 'frm_show_submit_button', $show, $form );
869
		return $show;
870
	}
871
872
	/**
873
	 * @since 2.3
874
	 */
875
	public static function get_option( $atts ) {
876
		$form = $atts['form'];
877
		return isset( $form->options[ $atts['option'] ] ) ? $form->options[ $atts['option'] ] : $atts['default'];
878
	}
879
}
880