PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.2.03
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.2.03
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / models / FrmForm.php

FrmForm.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 5.2.03, at classes/models/FrmForm.php

1,012 lines 28.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 * @param array $values
10 * @return int|boolean id on success or false on failure
11 */
12 public static function create( $values ) {
13 global $wpdb;
14
15 $values = FrmAppHelper::maybe_filter_array( $values, array( 'name', 'description' ) );
16
17 $new_values = array(
18 'form_key' => FrmAppHelper::get_unique_key( $values['form_key'], $wpdb->prefix . 'frm_forms', 'form_key' ),
19 'name' => $values['name'],
20 'description' => $values['description'],
21 'status' => isset( $values['status'] ) ? $values['status'] : 'published',
22 'logged_in' => isset( $values['logged_in'] ) ? $values['logged_in'] : 0,
23 'is_template' => isset( $values['is_template'] ) ? (int) $values['is_template'] : 0,
24 'parent_form_id' => isset( $values['parent_form_id'] ) ? absint( $values['parent_form_id'] ) : 0,
25 'editable' => isset( $values['editable'] ) ? (int) $values['editable'] : 0,
26 'created_at' => isset( $values['created_at'] ) ? $values['created_at'] : current_time( 'mysql', 1 ),
27 );
28
29 $options = isset( $values['options'] ) ? (array) $values['options'] : array();
30 FrmFormsHelper::fill_form_options( $options, $values );
31
32 $options['before_html'] = isset( $values['options']['before_html'] ) ? $values['options']['before_html'] : FrmFormsHelper::get_default_html( 'before' );
33 $options['after_html'] = isset( $values['options']['after_html'] ) ? $values['options']['after_html'] : FrmFormsHelper::get_default_html( 'after' );
34 $options['submit_html'] = isset( $values['options']['submit_html'] ) ? $values['options']['submit_html'] : FrmFormsHelper::get_default_html( 'submit' );
35
36 $options = apply_filters( 'frm_form_options_before_update', $options, $values );
37 $options = self::maybe_filter_form_options( $options );
38 $new_values['options'] = serialize( $options );
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 * @since 5.0.08
52 *
53 * @param array $options
54 * @return array
55 */
56 private static function maybe_filter_form_options( $options ) {
57 if ( ! FrmAppHelper::allow_unfiltered_html() && ! empty( $options['submit_html'] ) ) {
58 $options['submit_html'] = FrmAppHelper::kses_submit_button( $options['submit_html'] );
59 }
60 return FrmAppHelper::maybe_filter_array( $options, array( 'submit_value', 'success_msg', 'before_html', 'after_html' ) );
61 }
62
63 /**
64 * @return int|boolean ID on success or false on failure
65 */
66 public static function duplicate( $id, $template = false, $copy_keys = false, $blog_id = false ) {
67 global $wpdb;
68
69 $values = self::getOne( $id, $blog_id );
70 if ( ! $values ) {
71 return false;
72 }
73
74 $new_key = $copy_keys ? $values->form_key : '';
75
76 $new_values = array(
77 'form_key' => FrmAppHelper::get_unique_key( $new_key, $wpdb->prefix . 'frm_forms', 'form_key' ),
78 'name' => $values->name,
79 'description' => $values->description,
80 'status' => $values->status ? $values->status : 'published',
81 'logged_in' => $values->logged_in ? $values->logged_in : 0,
82 'editable' => $values->editable ? $values->editable : 0,
83 'created_at' => current_time( 'mysql', 1 ),
84 'is_template' => $template ? 1 : 0,
85 );
86
87 if ( $blog_id ) {
88 $new_values['status'] = 'published';
89 $new_options = $values->options;
90 FrmAppHelper::unserialize_or_decode( $new_options );
91 $new_options['email_to'] = get_option( 'admin_email' );
92 $new_options['copy'] = false;
93 $new_values['options'] = $new_options;
94 } else {
95 $new_values['options'] = $values->options;
96 }
97
98 if ( is_array( $new_values['options'] ) ) {
99 $new_values['options'] = serialize( $new_values['options'] );
100 }
101
102 $query_results = $wpdb->insert( $wpdb->prefix . 'frm_forms', $new_values );
103
104 if ( $query_results ) {
105 // Clear form caching
106 self::clear_form_cache();
107
108 $form_id = $wpdb->insert_id;
109 FrmField::duplicate( $id, $form_id, $copy_keys, $blog_id );
110
111 // update form settings after fields are created
112 do_action( 'frm_after_duplicate_form', $form_id, $new_values, array( 'old_id' => $id ) );
113
114 return $form_id;
115 }
116
117 return false;
118 }
119
120 public static function after_duplicate( $form_id, $values ) {
121 $new_opts = $values['options'];
122 FrmAppHelper::unserialize_or_decode( $new_opts );
123 $values['options'] = $new_opts;
124
125 if ( isset( $new_opts['success_msg'] ) ) {
126 $new_opts['success_msg'] = FrmFieldsHelper::switch_field_ids( $new_opts['success_msg'] );
127 }
128
129 $new_opts = apply_filters( 'frm_after_duplicate_form_values', $new_opts, $form_id );
130
131 if ( $new_opts != $values['options'] ) {
132 global $wpdb;
133 $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'options' => maybe_serialize( $new_opts ) ), array( 'id' => $form_id ) );
134 }
135 }
136
137 /**
138 * @return int|boolean
139 */
140 public static function update( $id, $values, $create_link = false ) {
141 global $wpdb;
142
143 $values = FrmAppHelper::maybe_filter_array( $values, array( 'name', 'description' ) );
144
145 if ( ! isset( $values['status'] ) && ( $create_link || isset( $values['options'] ) || isset( $values['item_meta'] ) || isset( $values['field_options'] ) ) ) {
146 $values['status'] = 'published';
147 }
148
149 if ( isset( $values['form_key'] ) ) {
150 $values['form_key'] = FrmAppHelper::get_unique_key( $values['form_key'], $wpdb->prefix . 'frm_forms', 'form_key', $id );
151 }
152
153 $form_fields = array( 'form_key', 'name', 'description', 'status', 'parent_form_id' );
154
155 $new_values = self::set_update_options( array(), $values, array( 'form_id' => $id ) );
156
157 foreach ( $values as $value_key => $value ) {
158 if ( $value_key && in_array( $value_key, $form_fields ) ) {
159 $new_values[ $value_key ] = $value;
160 }
161 }
162
163 if ( isset( $values['new_status'] ) && ! empty( $values['new_status'] ) ) {
164 $new_values['status'] = $values['new_status'];
165 }
166
167 if ( ! empty( $new_values ) ) {
168 $query_results = $wpdb->update( $wpdb->prefix . 'frm_forms', $new_values, array( 'id' => $id ) );
169 if ( $query_results ) {
170 self::clear_form_cache();
171 }
172 } else {
173 $query_results = true;
174 }
175 unset( $new_values );
176
177 $values = self::update_fields( $id, $values );
178
179 do_action( 'frm_update_form', $id, $values );
180 do_action( 'frm_update_form_' . $id, $values );
181
182 return $query_results;
183 }
184
185 /**
186 * @param array $new_values
187 * @param array $values
188 * @param array $args
189 * @return array
190 */
191 public static function set_update_options( $new_values, $values, $args = array() ) {
192 if ( ! isset( $values['options'] ) ) {
193 return $new_values;
194 }
195
196 $options = isset( $values['options'] ) ? (array) $values['options'] : array();
197 FrmFormsHelper::fill_form_options( $options, $values );
198
199 $options['custom_style'] = isset( $values['options']['custom_style'] ) ? $values['options']['custom_style'] : 0;
200 $options['before_html'] = isset( $values['options']['before_html'] ) ? $values['options']['before_html'] : FrmFormsHelper::get_default_html( 'before' );
201 $options['after_html'] = isset( $values['options']['after_html'] ) ? $values['options']['after_html'] : FrmFormsHelper::get_default_html( 'after' );
202 $options['submit_html'] = ( isset( $values['options']['submit_html'] ) && '' !== $values['options']['submit_html'] ) ? $values['options']['submit_html'] : FrmFormsHelper::get_default_html( 'submit' );
203
204 if ( ! empty( $options['success_url'] ) && ! empty( $args['form_id'] ) ) {
205 $options['success_url'] = FrmFormsHelper::maybe_add_sanitize_url_attr( $options['success_url'], (int) $args['form_id'] );
206 $values['options']['success_url'] = $options['success_url'];
207 }
208
209 $options = apply_filters( 'frm_form_options_before_update', $options, $values );
210 $options = self::maybe_filter_form_options( $options );
211 $new_values['options'] = serialize( $options );
212
213 return $new_values;
214 }
215
216 /**
217 * @return array
218 */
219 public static function update_fields( $id, $values ) {
220
221 if ( ! isset( $values['item_meta'] ) && ! isset( $values['field_options'] ) ) {
222 return $values;
223 }
224
225 $all_fields = FrmField::get_all_for_form( $id );
226 if ( empty( $all_fields ) ) {
227 return $values;
228 }
229
230 if ( ! isset( $values['item_meta'] ) ) {
231 $values['item_meta'] = array();
232 }
233
234 $field_array = array();
235 $existing_keys = array_keys( $values['item_meta'] );
236 foreach ( $all_fields as $fid ) {
237 if ( ! in_array( $fid->id, $existing_keys ) && ( isset( $values['frm_fields_submitted'] ) && in_array( $fid->id, $values['frm_fields_submitted'] ) ) || isset( $values['options'] ) ) {
238 $values['item_meta'][ $fid->id ] = '';
239 }
240 $field_array[ $fid->id ] = $fid;
241 }
242 unset( $all_fields );
243
244 foreach ( $values['item_meta'] as $field_id => $default_value ) {
245 if ( isset( $field_array[ $field_id ] ) ) {
246 $field = $field_array[ $field_id ];
247 } else {
248 $field = FrmField::getOne( $field_id );
249 }
250
251 if ( ! $field ) {
252 continue;
253 }
254
255 $is_settings_page = ( isset( $values['options'] ) || isset( $values['field_options'][ 'custom_html_' . $field_id ] ) );
256 if ( $is_settings_page ) {
257 self::get_settings_page_html( $values, $field );
258
259 if ( ! defined( 'WP_IMPORTING' ) ) {
260 continue;
261 }
262 }
263
264 //updating the form
265 $update_options = FrmFieldsHelper::get_default_field_options_from_field( $field );
266 unset( $update_options['custom_html'] ); // don't check for POST html
267 $update_options = apply_filters( 'frm_field_options_to_update', $update_options );
268
269 foreach ( $update_options as $opt => $default ) {
270 $field->field_options[ $opt ] = isset( $values['field_options'][ $opt . '_' . $field_id ] ) ? $values['field_options'][ $opt . '_' . $field_id ] : $default;
271 self::sanitize_field_opt( $opt, $field->field_options[ $opt ] );
272 }
273
274 $field->field_options = apply_filters( 'frm_update_field_options', $field->field_options, $field, $values );
275
276 $new_field = array(
277 'field_options' => $field->field_options,
278 'default_value' => isset( $values[ 'default_value_' . $field_id ] ) ? FrmAppHelper::maybe_json_encode( $values[ 'default_value_' . $field_id ] ) : '',
279 );
280
281 self::prepare_field_update_values( $field, $values, $new_field );
282
283 FrmField::update( $field_id, $new_field );
284
285 FrmField::delete_form_transient( $field->form_id );
286 }
287 self::clear_form_cache();
288
289 return $values;
290 }
291
292 private static function sanitize_field_opt( $opt, &$value ) {
293 if ( is_string( $value ) ) {
294 if ( $opt === 'calc' ) {
295 $value = self::sanitize_calc( $value );
296 } else {
297 $value = FrmAppHelper::kses( $value, 'all' );
298 }
299 $value = trim( $value );
300 }
301 }
302
303 /**
304 * @param string $value
305 * @return string
306 */
307 private static function sanitize_calc( $value ) {
308 if ( false !== strpos( $value, '<' ) ) {
309 $value = self::normalize_calc_spaces( $value );
310 }
311 $allow = array( '<= ', ' >=' ); // Allow <= and >=
312 $temp = array( '< = ', ' > =' );
313 $value = str_replace( $allow, $temp, $value );
314 $value = strip_tags( $value );
315 $value = str_replace( $temp, $allow, $value );
316 return $value;
317 }
318
319 /**
320 * Format a comparison like 5<10 to 5 < 10. Also works on 5< 10, 5 <10, 5<=10 variations.
321 * This is to avoid an issue with unspaced calculations being recognized as HTML that gets removed when strip_tags is called.
322 *
323 * @param string $calc
324 * @return string
325 */
326 private static function normalize_calc_spaces( $calc ) {
327 // Check for a pattern with 5 parts
328 // $1 \d the first comparison digit.
329 // $2 a space (optional).
330 // $3 an equals sign (optional) that follows the < operator for <= comparisons.
331 // $4 another space (optional).
332 // $5 \d the second comparison digit.
333 return preg_replace( '/(\d)( ){0,1}<(=){0,1}( ){0,1}(\d)/', '$1 <$3 $5', $calc );
334 }
335
336 /**
337 * Updating the settings page
338 */
339 private static function get_settings_page_html( $values, &$field ) {
340 if ( isset( $values['field_options'][ 'custom_html_' . $field->id ] ) ) {
341 $prev_opts = array();
342 $fallback_html = isset( $field->field_options['custom_html'] ) ? $field->field_options['custom_html'] : FrmFieldsHelper::get_default_html( $field->type );
343
344 $field->field_options['custom_html'] = isset( $values['field_options'][ 'custom_html_' . $field->id ] ) ? $values['field_options'][ 'custom_html_' . $field->id ] : $fallback_html;
345 } elseif ( $field->type == 'hidden' || $field->type == 'user_id' ) {
346 $prev_opts = $field->field_options;
347 }
348
349 if ( isset( $prev_opts ) ) {
350 $field->field_options = apply_filters( 'frm_update_form_field_options', $field->field_options, $field, $values );
351 if ( $prev_opts != $field->field_options ) {
352 FrmField::update( $field->id, array( 'field_options' => $field->field_options ) );
353 }
354 }
355 }
356
357 private static function prepare_field_update_values( $field, $values, &$new_field ) {
358 $field_cols = array(
359 'field_order' => 0,
360 'field_key' => '',
361 'required' => false,
362 'type' => '',
363 'description' => '',
364 'options' => '',
365 'name' => '',
366 );
367 foreach ( $field_cols as $col => $default ) {
368 $default = ( $default === '' ) ? $field->{$col} : $default;
369
370 $new_field[ $col ] = isset( $values['field_options'][ $col . '_' . $field->id ] ) ? $values['field_options'][ $col . '_' . $field->id ] : $default;
371 }
372
373 // Don't save the template option.
374 if ( is_array( $new_field['options'] ) && isset( $new_field['options']['000'] ) ) {
375 unset( $new_field['options']['000'] );
376 }
377 }
378
379 /**
380 * Get a list of all form settings that should be translated
381 * on a multilingual site.
382 *
383 * @since 3.06.01
384 * @param object $form - The form object
385 */
386 public static function translatable_strings( $form ) {
387 $strings = array(
388 'name',
389 'description',
390 'submit_value',
391 'submit_msg',
392 'success_msg',
393 );
394
395 return apply_filters( 'frm_form_strings', $strings, $form );
396 }
397
398 /**
399 * @param string $status
400 *
401 * @return int|boolean
402 */
403 public static function set_status( $id, $status ) {
404 if ( 'trash' == $status ) {
405 return self::trash( $id );
406 }
407
408 $statuses = array( 'published', 'draft', 'trash' );
409 if ( ! in_array( $status, $statuses ) ) {
410 return false;
411 }
412
413 global $wpdb;
414
415 if ( is_array( $id ) ) {
416 $where = array(
417 'id' => $id,
418 'parent_form_id' => $id,
419 'or' => 1,
420 );
421 FrmDb::get_where_clause_and_values( $where );
422 array_unshift( $where['values'], $status );
423
424 $query_results = $wpdb->query( $wpdb->prepare( 'UPDATE ' . $wpdb->prefix . 'frm_forms SET status = %s ' . $where['where'], $where['values'] ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
425 } else {
426 $query_results = $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'status' => $status ), array( 'id' => $id ) );
427 $wpdb->update( $wpdb->prefix . 'frm_forms', array( 'status' => $status ), array( 'parent_form_id' => $id ) );
428 }
429
430 if ( $query_results ) {
431 self::clear_form_cache();
432 }
433
434 return $query_results;
435 }
436
437 /**
438 * @return int|boolean
439 */
440 public static function trash( $id ) {
441 if ( ! EMPTY_TRASH_DAYS ) {
442 return self::destroy( $id );
443 }
444
445 $form = self::getOne( $id );
446 if ( ! $form ) {
447 return false;
448 }
449
450 $options = $form->options;
451 $options['trash_time'] = time();
452
453 global $wpdb;
454 $query_results = $wpdb->update(
455 $wpdb->prefix . 'frm_forms',
456 array(
457 'status' => 'trash',
458 'options' => serialize( $options ),
459 ),
460 array(
461 'id' => $id,
462 )
463 );
464
465 $wpdb->update(
466 $wpdb->prefix . 'frm_forms',
467 array(
468 'status' => 'trash',
469 'options' => serialize( $options ),
470 ),
471 array(
472 'parent_form_id' => $id,
473 )
474 );
475
476 if ( $query_results ) {
477 self::clear_form_cache();
478 }
479
480 return $query_results;
481 }
482
483 /**
484 * @return int|boolean
485 */
486 public static function destroy( $id ) {
487 global $wpdb;
488
489 $form = self::getOne( $id );
490 if ( ! $form ) {
491 return false;
492 }
493 $id = $form->id;
494
495 // Disconnect the entries from this form
496 $entries = FrmDb::get_col( $wpdb->prefix . 'frm_items', array( 'form_id' => $id ) );
497 foreach ( $entries as $entry_id ) {
498 FrmEntry::destroy( $entry_id );
499 unset( $entry_id );
500 }
501
502 // Disconnect the fields from this form
503 $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 ) );
504
505 $query_results = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . $wpdb->prefix . 'frm_forms WHERE id=%d OR parent_form_id=%d', $id, $id ) );
506 if ( $query_results ) {
507 // Delete all form actions linked to this form
508 $action_control = FrmFormActionsController::get_form_actions( 'email' );
509 $action_control->destroy( $id, 'all' );
510
511 // Clear form caching
512 self::clear_form_cache();
513
514 do_action( 'frm_destroy_form', $id );
515 do_action( 'frm_destroy_form_' . $id );
516 }
517
518 return $query_results;
519 }
520
521 /**
522 * Delete trashed forms based on how long they have been trashed
523 *
524 * @return int The number of forms deleted
525 */
526 public static function scheduled_delete( $delete_timestamp = '' ) {
527 global $wpdb;
528
529 $trash_forms = FrmDb::get_results( $wpdb->prefix . 'frm_forms', array( 'status' => 'trash' ), 'id, options' );
530
531 if ( ! $trash_forms ) {
532 return 0;
533 }
534
535 if ( empty( $delete_timestamp ) ) {
536 $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
537 }
538
539 $count = 0;
540 foreach ( $trash_forms as $form ) {
541 FrmAppHelper::unserialize_or_decode( $form->options );
542 if ( ! isset( $form->options['trash_time'] ) || $form->options['trash_time'] < $delete_timestamp ) {
543 self::destroy( $form->id );
544 $count ++;
545 }
546
547 unset( $form );
548 }
549
550 return $count;
551 }
552
553 /**
554 * @return string form name
555 */
556 public static function getName( $id ) {
557 $form = FrmDb::check_cache( $id, 'frm_form' );
558 if ( $form ) {
559 $r = stripslashes( $form->name );
560
561 return $r;
562 }
563
564 $query_key = is_numeric( $id ) ? 'id' : 'form_key';
565 $r = FrmDb::get_var( 'frm_forms', array( $query_key => $id ), 'name' );
566 $r = stripslashes( $r );
567
568 return $r;
569 }
570
571 /**
572 * @since 3.0
573 *
574 * @param string $key
575 *
576 * @return int form id
577 */
578 public static function get_id_by_key( $key ) {
579 return (int) FrmDb::get_var( 'frm_forms', array( 'form_key' => sanitize_title( $key ) ) );
580 }
581
582 /**
583 * @since 3.0
584 *
585 * @param int $id
586 *
587 * @return string form key
588 */
589 public static function get_key_by_id( $id ) {
590 $id = (int) $id;
591 $cache = FrmDb::check_cache( $id, 'frm_form' );
592 if ( $cache ) {
593 return $cache->form_key;
594 }
595
596 $key = FrmDb::get_var( 'frm_forms', array( 'id' => $id ), 'form_key' );
597
598 return $key;
599 }
600
601 /**
602 * If $form is numeric, get the form object
603 *
604 * @param object|int $form
605 *
606 * @since 2.0.9
607 */
608 public static function maybe_get_form( &$form ) {
609 if ( ! is_object( $form ) && ! is_array( $form ) && ! empty( $form ) ) {
610 $form = self::getOne( $form );
611 }
612 }
613
614 /**
615 * @return object form
616 */
617 public static function getOne( $id, $blog_id = false ) {
618 global $wpdb;
619
620 if ( $blog_id && is_multisite() ) {
621 global $wpmuBaseTablePrefix;
622 $prefix = $wpmuBaseTablePrefix ? $wpmuBaseTablePrefix . $blog_id . '_' : $wpdb->get_blog_prefix( $blog_id );
623
624 $table_name = $prefix . 'frm_forms';
625 } else {
626 $table_name = $wpdb->prefix . 'frm_forms';
627 $cache = wp_cache_get( $id, 'frm_form' );
628 if ( $cache ) {
629 if ( isset( $cache->options ) ) {
630 FrmAppHelper::unserialize_or_decode( $cache->options );
631 }
632
633 return wp_unslash( $cache );
634 }
635 }
636
637 if ( is_numeric( $id ) ) {
638 $where = array( 'id' => $id );
639 } else {
640 $where = array( 'form_key' => $id );
641 }
642
643 $results = FrmDb::get_row( $table_name, $where );
644
645 if ( isset( $results->options ) ) {
646 FrmDb::set_cache( $results->id, $results, 'frm_form' );
647 FrmAppHelper::unserialize_or_decode( $results->options );
648 }
649
650 return apply_filters( 'frm_form_object', wp_unslash( $results ) );
651 }
652
653 /**
654 * @return object|array of objects
655 */
656 public static function getAll( $where = array(), $order_by = '', $limit = '' ) {
657 if ( is_array( $where ) && ! empty( $where ) ) {
658 if ( isset( $where['is_template'] ) && $where['is_template'] && ! isset( $where['status'] ) && ! isset( $where['status !'] ) ) {
659 // don't get trashed templates
660 $where['status'] = array( null, '', 'published' );
661 }
662
663 $results = FrmDb::get_results( 'frm_forms', $where, '*', compact( 'order_by', 'limit' ) );
664 } else {
665 global $wpdb;
666
667 // the query has already been prepared if this is not an array
668 $query = 'SELECT * FROM ' . $wpdb->prefix . 'frm_forms' . FrmDb::prepend_and_or_where( ' WHERE ', $where ) . FrmDb::esc_order( $order_by ) . FrmDb::esc_limit( $limit );
669 $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
670 }
671
672 if ( $results ) {
673 foreach ( $results as $result ) {
674 FrmDb::set_cache( $result->id, $result, 'frm_form' );
675 FrmAppHelper::unserialize_or_decode( $result->options );
676 }
677 }
678
679 if ( $limit == ' LIMIT 1' || $limit == 1 ) {
680 // return the first form object if we are only getting one form
681 $results = reset( $results );
682 }
683
684 return wp_unslash( $results );
685 }
686
687 /**
688 * Get all published forms
689 *
690 * @since 2.0
691 * @return array of forms
692 */
693 public static function get_published_forms( $query = array(), $limit = 999, $inc_children = 'exclude' ) {
694 $query['is_template'] = 0;
695 $query['status'] = array( null, '', 'published' );
696 if ( $inc_children == 'exclude' ) {
697 $query['parent_form_id'] = array( null, 0 );
698 }
699
700 $forms = self::getAll( $query, 'name', $limit );
701
702 return $forms;
703 }
704
705 /**
706 * @return object count of forms
707 */
708 public static function get_count() {
709 global $wpdb;
710
711 $cache_key = 'frm_form_counts';
712
713 $counts = wp_cache_get( $cache_key, 'frm_form' );
714 if ( false !== $counts ) {
715 return $counts;
716 }
717
718 $results = (array) FrmDb::get_results(
719 'frm_forms',
720 array(
721 'or' => 1,
722 'parent_form_id' => null,
723 'parent_form_id <' => 0,
724 ),
725 'status, is_template'
726 );
727
728 $statuses = array( 'published', 'draft', 'template', 'trash' );
729 $counts = array_fill_keys( $statuses, 0 );
730
731 foreach ( $results as $row ) {
732 if ( 'trash' != $row->status ) {
733 if ( $row->is_template ) {
734 $counts['template'] ++;
735 } else {
736 $counts['published'] ++;
737 }
738 } else {
739 $counts['trash'] ++;
740 }
741
742 if ( 'draft' == $row->status ) {
743 $counts['draft'] ++;
744 }
745
746 unset( $row );
747 }
748
749 $counts = (object) $counts;
750 FrmDb::set_cache( $cache_key, $counts, 'frm_form' );
751
752 return $counts;
753 }
754
755 /**
756 * Clear form caching
757 * Called when a form is created, updated, duplicated, or deleted
758 * or when the form status is changed
759 *
760 * @since 2.0.4
761 */
762 public static function clear_form_cache() {
763 FrmDb::cache_delete_group( 'frm_form' );
764 }
765
766 /**
767 * @return array of errors
768 */
769 public static function validate( $values ) {
770 $errors = array();
771
772 return apply_filters( 'frm_validate_form', $errors, $values );
773 }
774
775 public static function get_params( $form = null ) {
776 global $frm_vars;
777
778 if ( ! $form ) {
779 $form = self::getAll( array(), 'name', 1 );
780 } else {
781 self::maybe_get_form( $form );
782 }
783
784 if ( isset( $frm_vars['form_params'] ) && is_array( $frm_vars['form_params'] ) && isset( $frm_vars['form_params'][ $form->id ] ) ) {
785 return $frm_vars['form_params'][ $form->id ];
786 }
787
788 $action_var = isset( $_REQUEST['frm_action'] ) ? 'frm_action' : 'action'; // phpcs:ignore WordPress.Security.NonceVerification.Missing
789 $action = apply_filters( 'frm_show_new_entry_page', FrmAppHelper::get_param( $action_var, 'new', 'get', 'sanitize_title' ), $form );
790
791 $default_values = array(
792 'id' => '',
793 'form_name' => '',
794 'paged' => 1,
795 'form' => $form->id,
796 'form_id' => $form->id,
797 'field_id' => '',
798 'search' => '',
799 'sort' => '',
800 'sdir' => '',
801 'action' => $action,
802 );
803
804 $values = array();
805 $values['posted_form_id'] = FrmAppHelper::get_param( 'form_id', '', 'get', 'absint' );
806 if ( ! $values['posted_form_id'] ) {
807 $values['posted_form_id'] = FrmAppHelper::get_param( 'form', '', 'get', 'absint' );
808 }
809
810 if ( $form->id == $values['posted_form_id'] ) {
811 //if there are two forms on the same page, make sure not to submit both
812 foreach ( $default_values as $var => $default ) {
813 if ( $var == 'action' ) {
814 $values[ $var ] = FrmAppHelper::get_param( $action_var, $default, 'get', 'sanitize_title' );
815 } else {
816 $values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
817 }
818 unset( $var, $default );
819 }
820 } else {
821 foreach ( $default_values as $var => $default ) {
822 $values[ $var ] = $default;
823 unset( $var, $default );
824 }
825 }
826
827 if ( in_array( $values['action'], array( 'create', 'update' ) ) &&
828 ( ! $_POST || ( ! isset( $_POST['action'] ) && ! isset( $_POST['frm_action'] ) ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
829 ) {
830 $values['action'] = 'new';
831 }
832
833 return $values;
834 }
835
836 public static function list_page_params() {
837 $values = array();
838 $defaults = array(
839 'template' => 0,
840 'id' => '',
841 'paged' => 1,
842 'form' => '',
843 'search' => '',
844 'sort' => '',
845 'sdir' => '',
846 );
847 foreach ( $defaults as $var => $default ) {
848 $values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
849 }
850
851 return $values;
852 }
853
854 public static function get_admin_params( $form = null ) {
855 $form_id = $form;
856 if ( $form === null ) {
857 $form_id = self::get_current_form_id();
858 } elseif ( $form && is_object( $form ) ) {
859 $form_id = $form->id;
860 }
861
862 $values = array();
863 $defaults = array(
864 'id' => '',
865 'form_name' => '',
866 'paged' => 1,
867 'form' => $form_id,
868 'field_id' => '',
869 'search' => '',
870 'sort' => '',
871 'sdir' => '',
872 'fid' => '',
873 'keep_post' => '',
874 );
875 foreach ( $defaults as $var => $default ) {
876 $values[ $var ] = FrmAppHelper::get_param( $var, $default, 'get', 'sanitize_text_field' );
877 }
878
879 return $values;
880 }
881
882 public static function get_current_form_id( $default_form = 'none' ) {
883 if ( 'first' == $default_form ) {
884 $form = self::get_current_form();
885 } else {
886 $form = self::maybe_get_current_form();
887 }
888 $form_id = $form ? $form->id : 0;
889
890 return $form_id;
891 }
892
893 public static function maybe_get_current_form( $form_id = 0 ) {
894 global $frm_vars;
895
896 if ( isset( $frm_vars['current_form'] ) && $frm_vars['current_form'] && ( ! $form_id || $form_id == $frm_vars['current_form']->id ) ) {
897 return $frm_vars['current_form'];
898 }
899
900 $form_id = FrmAppHelper::get_param( 'form', $form_id, 'get', 'absint' );
901 if ( $form_id ) {
902 $form_id = self::set_current_form( $form_id );
903 }
904
905 return $form_id;
906 }
907
908 public static function get_current_form( $form_id = 0 ) {
909 $form = self::maybe_get_current_form( $form_id );
910 if ( is_numeric( $form ) ) {
911 $form = self::set_current_form( $form );
912 }
913
914 return $form;
915 }
916
917 public static function set_current_form( $form_id ) {
918 global $frm_vars;
919
920 $query = array();
921 if ( $form_id ) {
922 $query['id'] = $form_id;
923 }
924
925 $frm_vars['current_form'] = self::get_published_forms( $query, 1 );
926
927 return $frm_vars['current_form'];
928 }
929
930 public static function is_form_loaded( $form, $this_load, $global_load ) {
931 global $frm_vars;
932 $small_form = new stdClass();
933 foreach ( array( 'id', 'form_key', 'name' ) as $var ) {
934 $small_form->{$var} = $form->{$var};
935 unset( $var );
936 }
937
938 $frm_vars['forms_loaded'][] = $small_form;
939
940 if ( $this_load && empty( $global_load ) ) {
941 $global_load = true;
942 $frm_vars['load_css'] = true;
943 }
944
945 return ( ( ! isset( $frm_vars['css_loaded'] ) || ! $frm_vars['css_loaded'] ) && $global_load );
946 }
947
948 /**
949 * @since 4.06.03
950 *
951 * @param object $form
952 *
953 * @return bool
954 */
955 public static function &is_visible_to_user( $form ) {
956 if ( $form->logged_in && isset( $form->options['logged_in_role'] ) ) {
957 $visible = FrmAppHelper::user_has_permission( $form->options['logged_in_role'] );
958 } else {
959 $visible = true;
960 }
961
962 return $visible;
963 }
964
965 public static function show_submit( $form ) {
966 $show = ( ! $form->is_template && $form->status == 'published' && ! FrmAppHelper::is_admin() );
967 $show = apply_filters( 'frm_show_submit_button', $show, $form );
968
969 return $show;
970 }
971
972 /**
973 * @since 2.3
974 */
975 public static function get_option( $atts ) {
976 $form = $atts['form'];
977 $default = isset( $atts['default'] ) ? $atts['default'] : '';
978
979 return isset( $form->options[ $atts['option'] ] ) ? $form->options[ $atts['option'] ] : $default;
980 }
981
982 /**
983 * Get the link to edit this form.
984 *
985 * @since 4.0
986 * @param int $form_id The id of the form.
987 */
988 public static function get_edit_link( $form_id ) {
989 return admin_url( 'admin.php?page=formidable&frm_action=edit&id=' . $form_id );
990 }
991
992 /**
993 * @deprecated 3.0
994 * @codeCoverageIgnore
995 *
996 * @param string $key
997 *
998 * @return int form id
999 */
1000 public static function getIdByKey( $key ) {
1001 return FrmFormDeprecated::getIdByKey( $key );
1002 }
1003
1004 /**
1005 * @deprecated 3.0
1006 * @codeCoverageIgnore
1007 */
1008 public static function getKeyById( $id ) {
1009 return FrmFormDeprecated::getKeyById( $id );
1010 }
1011 }
1012