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

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