PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.6.16
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.6.16
1.6.7 1.6.8 1.6.9 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.18 1.6.19 1.6.2 1.6.20 1.6.21 1.6.22 1.6.23 1.6.24 1.6.25 1.6.26 1.6.27 1.6.28 1.6.3 1.6.4 1.6.5 1.6.6 All 74 releases
weforms / includes / class-form.php

class-form.php in weForms – Easy Drag & Drop Contact Form Builder For WordPress 1.6.16, at includes/class-form.php

635 lines 20.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The Form Class
5 *
6 * @since 1.1.0
7 */
8 class WeForms_Form {
9
10 /**
11 * The form id
12 *
13 * @var int
14 */
15 public $id = 0;
16
17 /**
18 * The form title
19 *
20 * @var string
21 */
22 public $name = '';
23
24 /**
25 * Holds the post data object
26 *
27 * @var WP_post|null
28 */
29 public $data = null;
30
31 /**
32 * Form fields
33 *
34 * @var array
35 */
36 public $form_fields = [];
37
38 /**
39 * The Constructor
40 *
41 * @param int|WP_Post $form
42 */
43 public function __construct( $form = null ) {
44 if ( is_numeric( $form ) ) {
45 $the_post = get_post( $form );
46
47 if ( $the_post ) {
48 $this->id = $the_post->ID;
49 $this->name = $the_post->post_title;
50 $this->data = $the_post;
51 }
52 } elseif ( is_a( $form, 'WP_Post' ) ) {
53 $this->id = $form->ID;
54 $this->name = $form->post_title;
55 $this->data = $form;
56 }
57 }
58
59 /**
60 * Get the form ID
61 *
62 * @return int
63 */
64 public function get_id() {
65 return $this->id;
66 }
67
68 /**
69 * Get the form name
70 *
71 * @return string
72 */
73 public function get_name() {
74 return $this->name;
75 }
76
77 /**
78 * Get all form fields of this form
79 *
80 * @return array
81 */
82 public function get_fields() {
83
84 // return if already fetched
85 if ( $this->form_fields ) {
86 return $this->form_fields;
87 }
88
89 $fields = get_children( [
90 'post_parent' => $this->id,
91 'post_status' => 'publish',
92 'post_type' => 'wpuf_input',
93 'numberposts' => '-1',
94 'orderby' => 'menu_order',
95 'order' => 'ASC',
96 ] );
97
98 $form_fields = [];
99
100 foreach ( $fields as $key => $content ) {
101 $field = maybe_unserialize( $content->post_content );
102
103 if ( empty( $field['template'] ) ) {
104 continue;
105 }
106
107 $field['id'] = $content->ID;
108
109 // Add inline property for radio and checkbox fields
110 $inline_supported_fields = apply_filters( 'inline_supported_fields_list', [ 'radio_field', 'checkbox_field' ] );
111
112 if ( in_array( $field['template'], $inline_supported_fields ) ) {
113 if ( !isset( $field['inline'] ) ) {
114 $field['inline'] = 'no';
115 }
116 }
117
118 // Add 'selected' property
119 $option_based_fields = apply_filters( 'option_based_fields_list', [ 'dropdown_field', 'multiple_select', 'radio_field', 'checkbox_field' ] );
120
121 if ( in_array( $field['template'], $option_based_fields ) ) {
122 if ( !isset( $field['selected'] ) ) {
123 if ( 'dropdown_field' === $field['template'] || 'radio_field' === $field['template'] ) {
124 $field['selected'] = '';
125 } else {
126 $field['selected'] = [];
127 }
128 }
129 }
130
131 // Add 'multiple' key for template:repeat
132 if ( 'repeat_field' === $field['template'] && !isset( $field['multiple'] ) ) {
133 $field['multiple'] = '';
134 }
135
136 if ( 'recaptcha' === $field['template'] ) {
137 $field['name'] = 'recaptcha';
138 $field['enable_no_captcha'] = isset( $field['enable_no_captcha'] ) ? $field['enable_no_captcha'] : '';
139 $field['recaptcha_theme'] = isset( $field['recaptcha_theme'] ) ? $field['recaptcha_theme'] : 'light';
140 }
141
142 // Check if meta_key has changed when saving form compared current entries
143 if ( isset( $field['name'] ) ) {
144 $field['original_name'] = $field['name'];
145 }
146 $form_fields[] = apply_filters( 'weforms-get-form-field', $field, $this->id );
147 }
148
149 $this->form_fields = apply_filters( 'weforms-get-form-fields', $form_fields, $this->id );
150
151 return $this->form_fields;
152 }
153
154 /**
155 * Check if any perticular field template is used in a form
156 *
157 * @return array
158 */
159 public function has_field( $field_template ) {
160 foreach ( $this->get_fields() as $key => $field ) {
161 if ( isset( $field['template'] ) && $field['template'] == $field_template ) {
162 return true;
163 }
164 }
165 }
166
167 /**
168 * Get all fields by a template
169 *
170 * @return array
171 */
172 public function search_fields( $field_template ) {
173 $fields = [];
174
175 foreach ( $this->get_fields() as $key => $field ) {
176 if ( isset( $field['template'] ) && $field['template'] == $field_template ) {
177 $fields[] = $field;
178 }
179 }
180
181 return $fields;
182 }
183
184 /**
185 * Search fileds and get the first one
186 *
187 * @return array
188 */
189 public function search_field( $field_template ) {
190 $fields = $this->search_fields( $field_template );
191
192 return isset( $fields[0] ) ? $fields[0] : [];
193 }
194
195 /**
196 * Get formatted field name/values
197 *
198 * @return array
199 */
200 public function get_field_values() {
201 $values = [];
202 $fields = $this->get_fields();
203
204 if ( !$fields ) {
205 return $values;
206 }
207
208 $ignore_fields = apply_filters( 'ignore_fields_list', [ 'recaptcha', 'section_break' ] );
209 $options_fields = apply_filters( 'option_fields_list', [ 'dropdown_field', 'radio_field', 'multiple_select', 'checkbox_field' ] );
210
211 foreach ( $fields as $field ) {
212 if ( in_array( $field['template'], $ignore_fields ) ) {
213 continue;
214 }
215
216 // Prepare column field data
217 if ( $field['template'] == 'column_field' ) {
218 $inner_columns = $field['inner_fields'];
219
220 if ( !empty( $inner_columns ) ) {
221 foreach ( $inner_columns as $column => $column_fields ) {
222 if ( !empty( $column_fields ) ) {
223 foreach ( $column_fields as $field_obj ) {
224 if ( in_array( $field_obj['template'], $ignore_fields ) ) {
225 continue;
226 }
227
228 if ( !isset( $field_obj['name'] ) ) {
229 continue;
230 }
231
232 $field_value = [
233 'label' => isset( $field_obj['label'] ) ? $field_obj['label'] : '',
234 'type' => $field_obj['template'],
235 ];
236
237 // put options if this is an option field
238 if ( in_array( $field_obj['template'], $options_fields ) ) {
239 $field_value['options'] = $field_obj['options'];
240 }
241
242 $values[ $field_obj['name'] ] = array_merge( $field_obj, $field_value );
243 }
244 }
245 }
246 }
247 }
248
249 if ( !isset( $field['name'] ) ) {
250 continue;
251 }
252
253 $value = [
254 'label' => isset( $field['label'] ) ? $field['label'] : '',
255 'type' => $field['template'],
256 ];
257
258 // put options if this is an option field
259 if ( in_array( $field['template'], $options_fields ) ) {
260 $value['options'] = $field['options'];
261 }
262
263 $values[ $field['name'] ] = array_merge( $field, $value );
264 }
265
266 return apply_filters( 'weforms_get_field_values', $values );
267 }
268
269 /**
270 * Get form settings
271 *
272 * @return array
273 */
274 public function get_settings() {
275 $settings = get_post_meta( $this->id, 'wpuf_form_settings', true );
276 $default = weforms_get_default_form_settings();
277
278 return apply_filters( 'weforms-get-form-settings', array_merge( $default, $settings ), $this->id );
279 }
280
281 /**
282 * Check if the form submission is open
283 *
284 * @return bool|WP_Error
285 */
286 public function is_submission_open() {
287 $settings = $this->get_settings();
288
289 $needs_login = ( isset( $settings['require_login'] ) && $settings['require_login'] == 'true' ) ? true : false;
290 $has_limit = ( isset( $settings['limit_entries'] ) && $settings['limit_entries'] == 'true' ) ? true : false;
291 $is_scheduled = ( isset( $settings['schedule_form'] ) && $settings['schedule_form'] == 'true' ) ? true : false;
292
293 if ( $this->data->post_status != 'publish' ) {
294 return new WP_Error( 'needs-publish', __( 'The form is not published yet.', 'weforms' ) );
295 }
296
297 if ( $needs_login && !is_user_logged_in() ) {
298 return new WP_Error( 'needs-login', $settings['req_login_message'] );
299 }
300
301 if ( $has_limit ) {
302 $limit = (int) $settings['limit_number'];
303 $form_entries = $this->num_form_entries();
304
305 if ( $limit <= $form_entries ) {
306 return new WP_Error( 'entry-limit', $settings['limit_message'] );
307 }
308 }
309
310 if ( $is_scheduled ) {
311 $start_time = strtotime( $settings['schedule_start'] );
312 $end_time = strtotime( $settings['schedule_end'] );
313 $current_time = current_time( 'timestamp' );
314
315 // too early?
316 if ( $current_time < $start_time ) {
317 return new WP_Error( 'form-pending', $settings['sc_pending_message'] );
318 } elseif ( $current_time > $end_time ) {
319 return new WP_Error( 'form-expired', $settings['sc_expired_message'] );
320 }
321 }
322
323 return apply_filters( 'weforms_is_submission_open', true, $settings, $this );
324 }
325
326 /**
327 * Get form notifications
328 *
329 * @return array
330 */
331 public function get_notifications() {
332 $notifications = get_post_meta( $this->id, 'notifications', true );
333 $defualt = weforms_get_default_form_notification();
334
335 if ( !$notifications ) {
336 $notifications = [];
337 }
338
339 $notifications = array_map( function ( $notification ) use ( $defualt ) {
340 if ( empty( $notification ) ) {
341 $notification = [];
342 }
343
344 return array_merge( $defualt, $notification );
345 }, $notifications );
346
347 return $notifications;
348 }
349
350 /**
351 * Get all the integrations
352 *
353 * @return array
354 */
355 public function get_integrations() {
356 $integrations = get_post_meta( $this->id, 'integrations', true );
357
358 if ( !$integrations ) {
359 return [];
360 }
361
362 return $integrations;
363 }
364
365 /**
366 * Get entries of this form
367 *
368 * @return \WeForms_Form_Entry_Manager
369 */
370 public function entries() {
371 return new WeForms_Form_Entry_Manager( $this->id, $this );
372 }
373
374 /**
375 * When a user is editing their form they may change a fields name.
376 * This method will loop through existing entries to match the new field names.
377 *
378 * @since 1.6.9
379 *
380 * @param int $form_id
381 * @param array $form_fields
382 */
383 public function maybe_update_entries( $form_fields ) {
384 $changed_fields = $this->get_changed_fields( $form_fields );
385 // Loop through changed fields and update entries
386 foreach ( $changed_fields as $old => $new) {
387 $updated_fields = $this->rename_field( $old, $new );
388 }
389 }
390
391 /**
392 * When a user is editing their form they may change a fields name.
393 * This method will loop through all fields that have changed.
394 *
395 * @since 1.6.9
396 *
397 * @param int $form_id
398 * @param array $form_fields
399 *
400 * @return array
401 */
402 public function get_changed_fields( $form_fields ) {
403 $changed_fields = array();
404 foreach ( $form_fields as $field ) {
405 $org_field = $field['original_name'];
406 // All form fields should have an original name.
407 if ( empty( $field['original_name'] ) ) {
408 continue;
409 }
410 if ( $field['name'] !== $field['original_name'] ) {
411 $changed_fields[$field['original_name']] = $field['name'];
412 } else {
413 continue;
414 }
415 }
416 return $changed_fields;
417
418 }
419
420 /**
421 * When a user changes the field names of a form, the existing entries will need updated.
422 * This method will loop through the existing entries and update them will the new names.
423 *
424 * @since 1.6.9
425 *
426 * @param int $form_id
427 * @param array $form_fields
428 *
429 * @return array
430 */
431 public function rename_field ( $old, $new ) {
432 global $wpdb;
433
434 $entries = weforms_get_form_entries( $this->id );
435
436 foreach ( $entries as $entry ) {
437 $entry_id = $entry->id;
438 $values = weforms_get_entry_meta( $entry_id );
439 $update_keys = $wpdb->update( $wpdb->weforms_entrymeta, array( 'meta_key' => $new ), array( 'meta_key' => $old, 'weforms_entry_id' => $entry_id ) );
440 }
441 }
442
443 /**
444 * Get number of form entries
445 *
446 * @return int
447 */
448 public function num_form_entries() {
449 return weforms_count_form_entries( $this->id );
450 }
451
452 /**
453 * Get number of form payments
454 *
455 * @return int
456 */
457 public function num_form_payments() {
458 return weforms_count_form_payments( $this->id );
459 }
460
461 /**
462 * Get form author details
463 *
464 * @return array
465 */
466 public function get_form_author_details() {
467 return weforms_get_form_author_details( $this->id );
468 }
469
470 /**
471 * Get the number of form views
472 *
473 * @return int
474 */
475 public function num_form_views() {
476 return weforms_get_form_views( $this->id );
477 }
478
479 /**
480 * prepare_entries
481 *
482 * @return array
483 */
484 public function prepare_entries( $args = [] ) {
485 $fields = weforms()->fields->get_fields();
486 $form_fields = $this->get_fields();
487
488 $entry_fields = [];
489
490 $ignore_list = apply_filters( 'wefroms_entry_ignore_list', [
491 'recaptcha', 'section_break', 'step_start',
492 ] );
493
494 foreach ( $form_fields as $field ) {
495 if ( in_array( $field['template'], $ignore_list ) ) {
496 continue;
497 }
498
499 if ( !array_key_exists( $field['template'], $fields ) ) {
500 continue;
501 }
502
503 // Prepare column field data
504 if ( $field['template'] == 'column_field' ) {
505 $inner_columns = $field['inner_fields'];
506
507 if ( !empty( $inner_columns ) ) {
508 foreach ( $inner_columns as $column => $column_fields ) {
509 if ( !empty( $column_fields ) ) {
510 foreach ( $column_fields as $field_obj ) {
511 if ( in_array( $field_obj['template'], $ignore_list ) ) {
512 continue;
513 }
514
515 $fieldClass = $fields[ $field_obj['template'] ];
516 $entry_fields[ $field_obj['name'] ] = $fieldClass->prepare_entry( $field_obj );
517 }
518 }
519 }
520 }
521 }
522
523 $field_class = $fields[ $field['template'] ];
524
525 $entry_fields[ $field['name'] ] = $field_class->prepare_entry( $field, $args );
526 }
527
528 return apply_filters( 'weforms_prepare_entries', $entry_fields );
529 }
530
531 /**
532 * Check if the form submission is open On API
533 *
534 * @return bool|WP_Error
535 */
536 public function is_api_form_submission_open() {
537 $response = [];
538 $settings = $this->get_settings();
539 $form_entries = $this->num_form_entries();
540 $needs_login = isset( $settings['require_login'] ) ? $settings['require_login'] : 'false';
541 $limit_entries = isset( $settings['limit_entries'] ) ? $settings['limit_entries'] : 'false';
542 $schedule_form = isset( $settings['schedule_form'] ) ? $settings['schedule_form'] : 'false';
543 $limit_number = isset( $settings['limit_number'] ) ? $settings['limit_number'] : '';
544 $schedule_start = isset( $settings['schedule_start'] ) ? $settings['schedule_start'] : '';
545 $schedule_end = isset( $settings['schedule_end'] ) ? $settings['schedule_end'] : '';
546 $schedule_start_date = date_i18n( 'M d, Y', strtotime( $schedule_start ) );
547 $schedule_end_date = date_i18n( 'M d, Y', strtotime( $schedule_end ) );
548
549 if ( $this->data->post_status != 'publish' ) {
550 $response['type'] = __( 'Closed', 'weforms' );
551 }
552
553 if ( $this->isFormStatusClosed( $settings, $form_entries ) ) {
554 $response['type'] = __( 'Closed', 'weforms' );
555 } else {
556 $response['type'] = __( 'Open', 'weforms' );
557 }
558
559 if ( $limit_entries === 'true' ) {
560 if ( $schedule_form === 'true' && $this->isExpiredForm( $schedule_end ) ) {
561 $response['message'] = __( "Expired at {$schedule_end_date}", 'weforms' );
562 } elseif ( $schedule_form === 'true' && $this->isPendingForm( $schedule_start ) ) {
563 $response['message'] = __( "Starts at {$schedule_start_date}", 'weforms' );
564 } elseif ( $form_entries >= $limit_number ) {
565 $response['message'] = __( 'Reached maximum entry limit', 'weforms' );
566 } else {
567 $remaining_entries = $limit_number - $form_entries;
568 $response['message'] = __( "{$remaining_entries} entries remaining ", 'weforms' );
569 }
570 } elseif ( $schedule_form === 'true' ) {
571 if ( $this->isPendingForm( $schedule_start ) ) {
572 $response['message'] = __( "Starts at {$schedule_start_date}", 'weforms' );
573 } elseif ( $this->isExpiredForm( $schedule_end ) ) {
574 $response['message'] = __( "Expired at {$schedule_end_date}", 'weforms' );
575 } elseif ( $this->isOpenForm( $schedule_start, $schedule_end ) ) {
576 $response['message'] = __( "Expires at {$schedule_end_date}", 'weforms' );
577 }
578 } elseif ( $needs_login === 'true' ) {
579 $response['message'] =__( 'Requires login', 'weforms' );
580 }
581
582 return apply_filters( 'weforms_is_submission_open', $response, $settings, $this );
583 }
584
585 public function isPendingForm( $scheduleStart ) {
586 $currentTime = current_time( 'timestamp' );
587 $startTime = strtotime( $scheduleStart );
588
589 if ( $currentTime < $startTime ) {
590 return true;
591 }
592
593 return false;
594 }
595
596 public function isExpiredForm( $scheduleEnd ) {
597 $currentTime = current_time( 'timestamp' );
598 $endTime = strtotime( $scheduleEnd );
599
600 if ( $currentTime > $endTime ) {
601 return true;
602 }
603
604 return false;
605 }
606
607 public function isOpenForm( $scheduleStart, $scheduleEnd ) {
608 $currentTime = current_time( 'timestamp' );
609 $startTime = strtotime( $scheduleStart );
610 $endTime = strtotime( $scheduleEnd );
611
612 if ( $currentTime > $startTime && $currentTime < $endTime ) {
613 return true;
614 }
615
616 return false;
617 }
618
619 public function isFormStatusClosed( $formSettings, $entries ) {
620 if ( $formSettings['schedule_form'] === 'true' && $this->isPendingForm( $formSettings['schedule_start'] ) ) {
621 return true;
622 }
623
624 if ( $formSettings['schedule_form'] === 'true' && $this->isExpiredForm( $formSettings['schedule_end'] ) ) {
625 return true;
626 }
627
628 if ( $formSettings['limit_entries'] === 'true' && $entries >= $formSettings['limit_number'] ) {
629 return true;
630 }
631
632 return false;
633 }
634 }
635