PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.0.14
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.0.14
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.0.14, at classes/models/FrmForm.php

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