PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.07.01
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.07.01
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
← All changes | classes/models/FrmEntryValidate.php +58 -443 6.5 → 4.07.01 View file →
@@ -3,14 +3,8 @@
3 3 die( 'You are not allowed to call this page directly.' );
4 4 }
5 5
6 6 class FrmEntryValidate {
7 -
8 - /**
9 - * @param array $values
10 - * @param string[]|bool $exclude
11 - * @return array
12 - */
13 7 public static function validate( $values, $exclude = false ) {
14 8 FrmEntry::sanitize_entry_post( $values );
15 9 $errors = array();
16 10
@@ -20,10 +14,9 @@
20 14 return $errors;
21 15 }
22 16
23 17 if ( FrmAppHelper::is_admin() && is_user_logged_in() && ( ! isset( $values[ 'frm_submit_entry_' . $values['form_id'] ] ) || ! wp_verify_nonce( $values[ 'frm_submit_entry_' . $values['form_id'] ], 'frm_submit_entry_nonce' ) ) ) {
24 - $frm_settings = FrmAppHelper::get_settings();
25 - $errors['form'] = $frm_settings->admin_permission;
18 + $errors['form'] = __( 'You do not have permission to do that', 'formidable' );
26 19 }
27 20
28 21 self::set_item_key( $values );
29 22
@@ -40,25 +33,10 @@
40 33 if ( empty( $errors ) ) {
41 34 self::spam_check( $exclude, $values, $errors );
42 35 }
43 36
44 - /**
45 - * Allows modifying the validation errors after validating all fields.
46 - *
47 - * @since 5.0.04 Added `posted_fields` to the third param.
48 - *
49 - * @param array $errors Errors data.
50 - * @param array $values Value data of the form.
51 - * @param array $args Custom arguments. Contains `exclude` and `posted_fields`.
52 - */
53 - $filtered_errors = apply_filters( 'frm_validate_entry', $errors, $values, compact( 'exclude', 'posted_fields' ) );
37 + $errors = apply_filters( 'frm_validate_entry', $errors, $values, compact( 'exclude' ) );
54 38
55 - if ( is_array( $filtered_errors ) ) {
56 - $errors = $filtered_errors;
57 - } else {
58 - _doing_it_wrong( __FUNCTION__, 'Only arrays should be returned when using the frm_validate_entry filter.', '6.3' );
59 - }
60 -
61 39 return $errors;
62 40 }
63 41
64 42 private static function set_item_key( &$values ) {
@@ -79,19 +57,9 @@
79 57 if ( ! empty( $exclude ) ) {
80 58 $where['fi.type not'] = $exclude;
81 59 }
82 60
83 - $fields = FrmField::getAll( $where, 'field_order' );
84 -
85 - /**
86 - * Allows modifying fields to validate.
87 - *
88 - * @since 5.0.06
89 - *
90 - * @param array $fields List of fields.
91 - * @param array $args Includes `values`, `exclude`, `where`.
92 - */
93 - return apply_filters( 'frm_fields_to_validate', $fields, compact( 'values', 'exclude', 'where' ) );
61 + return FrmField::getAll( $where, 'field_order' );
94 62 }
95 63
96 64 public static function validate_field( $posted_field, &$errors, $values, $args = array() ) {
97 65 $defaults = array(
@@ -124,10 +92,10 @@
124 92 }
125 93
126 94 if ( $posted_field->required == '1' && FrmAppHelper::is_empty_value( $value ) ) {
127 95 $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $posted_field, 'blank' );
128 - } elseif ( ! isset( $_POST['item_name'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
129 - self::maybe_add_item_name( $value, $posted_field );
96 + } elseif ( $posted_field->type == 'text' && ! isset( $_POST['item_name'] ) ) { // WPCS: CSRF ok.
97 + $_POST['item_name'] = $value;
130 98 }
131 99
132 100 FrmEntriesHelper::set_posted_value( $posted_field, $value, $args );
133 101
@@ -144,43 +112,23 @@
144 112 $errors = apply_filters( 'frm_validate_' . $posted_field->type . '_field_entry', $errors, $posted_field, $value, $args );
145 113 $errors = apply_filters( 'frm_validate_field_entry', $errors, $posted_field, $value, $args );
146 114 }
147 115
148 - /**
149 - * Maybe add item_name to $_POST to save it in items table.
150 - *
151 - * @since 5.2.02
152 - *
153 - * @param object $field Field object.
154 - */
155 - private static function maybe_add_item_name( $value, $field ) {
156 - $item_name = false;
157 - if ( 'name' === $field->type ) {
158 - $field_obj = FrmFieldFactory::get_field_object( $field );
159 - $item_name = $field_obj->get_display_value( $value );
160 - } elseif ( 'text' === $field->type ) {
161 - $item_name = $value;
162 - }
116 + private static function maybe_clear_value_for_default_blank_setting( $field, &$value ) {
117 + $placeholder = FrmField::get_option( $field, 'placeholder' );
118 + $is_default = ( ! empty( $placeholder ) && $value == $placeholder );
119 + $is_label = false;
163 120
164 - if ( false !== $item_name ) {
165 - // Item name has a max length of 255 characters so truncate it so it doesn't fail to save in the database.
166 - $_POST['item_name'] = substr( $item_name, 0, 255 );
167 - }
168 - }
121 + if ( ! $is_default ) {
122 + $position = FrmField::get_option( $field, 'label' );
123 + if ( empty( $position ) ) {
124 + $position = FrmStylesController::get_style_val( 'position', $field->form_id );
125 + }
169 126
170 - /**
171 - * Set $value to an empty string if it matches its label
172 - *
173 - * @param object $field
174 - * @param string $value
175 - */
176 - private static function maybe_clear_value_for_default_blank_setting( $field, &$value ) {
177 - $position = FrmField::get_option( $field, 'label' );
178 - if ( ! $position ) {
179 - $position = FrmStylesController::get_style_val( 'position', $field->form_id );
127 + $is_label = ( $position == 'inside' && FrmFieldsHelper::is_placeholder_field_type( $field->type ) && $value == $field->name );
180 128 }
181 129
182 - if ( $position === 'inside' && FrmFieldsHelper::is_placeholder_field_type( $field->type ) && $value === $field->name ) {
130 + if ( $is_label || $is_default ) {
183 131 $value = '';
184 132 }
185 133 }
186 134
@@ -282,62 +230,29 @@
282 230 // only check spam if there are no other errors
283 231 return;
284 232 }
285 233
286 - $antispam_check = self::is_antispam_check( $values['form_id'] );
287 - if ( is_string( $antispam_check ) ) {
288 - $errors['spam'] = $antispam_check;
289 - } elseif ( self::is_honeypot_spam( $values ) || self::is_spam_bot() ) {
234 + if ( self::is_honeypot_spam() || self::is_spam_bot() ) {
290 235 $errors['spam'] = __( 'Your entry appears to be spam!', 'formidable' );
291 - } elseif ( self::blacklist_check( $values ) ) {
292 - $errors['spam'] = __( 'Your entry appears to be blocked spam!', 'formidable' );
293 236 }
294 237
295 - if ( isset( $errors['spam'] ) || self::form_is_in_progress( $values ) ) {
296 - return;
238 + if ( self::blacklist_check( $values ) ) {
239 + $errors['spam'] = __( 'Your entry appears to be blocked spam!', 'formidable' );
297 240 }
298 241
299 - if ( self::is_akismet_enabled_for_user( $values['form_id'] ) && self::is_akismet_spam( $values ) ) {
300 - $errors['spam'] = __( 'Your entry appears to be spam!', 'formidable' );
242 + if ( self::is_akismet_spam( $values ) ) {
243 + if ( self::is_akismet_enabled_for_user( $values['form_id'] ) ) {
244 + $errors['spam'] = __( 'Your entry appears to be spam!', 'formidable' );
245 + }
301 246 }
302 247 }
303 248
304 - /**
305 - * Checks if form is in progress.
306 - *
307 - * @since 5.0.13
308 - *
309 - * @param array $values The values.
310 - * @return bool
311 - */
312 - private static function form_is_in_progress( $values ) {
313 - return FrmAppHelper::pro_is_installed() &&
314 - ( isset( $values[ 'frm_page_order_' . $values['form_id'] ] ) || FrmAppHelper::get_post_param( 'frm_next_page' ) ) &&
315 - FrmField::get_all_types_in_form( $values['form_id'], 'break' );
316 - }
249 + private static function is_honeypot_spam() {
250 + $honeypot_value = FrmAppHelper::get_param( 'frm_verify', '', 'get', 'sanitize_text_field' );
317 251
318 - /**
319 - * @param int $form_id
320 - *
321 - * @return bool|string
322 - */
323 - private static function is_antispam_check( $form_id ) {
324 - $aspm = new FrmAntiSpam( $form_id );
325 - return $aspm->validate();
252 + return ( $honeypot_value !== '' );
326 253 }
327 254
328 - /**
329 - * @param array $values
330 - * @return boolean
331 - */
332 - private static function is_honeypot_spam( $values ) {
333 - $honeypot = new FrmHoneypot( $values['form_id'] );
334 - return ! $honeypot->validate();
335 - }
336 -
337 - /**
338 - * @return boolean
339 - */
340 255 private static function is_spam_bot() {
341 256 $ip = FrmAppHelper::get_ip_address();
342 257
343 258 return empty( $ip );
@@ -342,12 +257,8 @@
342 257
343 258 return empty( $ip );
344 259 }
345 260
346 - /**
347 - * @param array $values
348 - * @return boolean
349 - */
350 261 private static function is_akismet_spam( $values ) {
351 262 global $wpcom_api_key;
352 263
353 264 return ( is_callable( 'Akismet::http_post' ) && ( get_option( 'wordpress_api_key' ) || $wpcom_api_key ) && self::akismet( $values ) );
@@ -352,16 +263,12 @@
352 263
353 264 return ( is_callable( 'Akismet::http_post' ) && ( get_option( 'wordpress_api_key' ) || $wpcom_api_key ) && self::akismet( $values ) );
354 265 }
355 266
356 - /**
357 - * @param int $form_id
358 - * @return bool
359 - */
360 267 private static function is_akismet_enabled_for_user( $form_id ) {
361 268 $form = FrmForm::getOne( $form_id );
362 269
363 - return ( ! empty( $form->options['akismet'] ) && ( $form->options['akismet'] !== 'logged' || ! is_user_logged_in() ) );
270 + return ( isset( $form->options['akismet'] ) && ! empty( $form->options['akismet'] ) && ( $form->options['akismet'] != 'logged' || ! is_user_logged_in() ) );
364 271 }
365 272
366 273 public static function blacklist_check( $values ) {
367 274 if ( ! apply_filters( 'frm_check_blacklist', true, $values ) ) {
@@ -373,10 +280,12 @@
373 280 return false;
374 281 }
375 282
376 283 $content = FrmEntriesHelper::entry_array_to_string( $values );
284 + if ( empty( $content ) ) {
285 + return false;
286 + }
377 287
378 - self::prepare_values_for_spam_check( $values );
379 288 $ip = FrmAppHelper::get_ip_address();
380 289 $user_agent = FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' );
381 290 $user_info = self::get_spam_check_user_info( $values );
382 291
@@ -415,26 +324,19 @@
415 324 *
416 325 * @return boolean true if is spam
417 326 */
418 327 public static function akismet( $values ) {
419 - if ( empty( $values['item_meta'] ) ) {
328 + $content = FrmEntriesHelper::entry_array_to_string( $values );
329 + if ( empty( $content ) ) {
420 330 return false;
421 331 }
422 332
423 333 $datas = array(
424 - 'comment_type' => 'formidable',
334 + 'comment_type' => 'formidable',
335 + 'comment_content' => $content,
425 336 );
426 337 self::parse_akismet_array( $datas, $values );
427 338
428 - /**
429 - * Allows modifying the values sent to Akismet.
430 - *
431 - * @since 5.0.07
432 - *
433 - * @param array $datas The array of values being sent to Akismet.
434 - */
435 - $datas = apply_filters( 'frm_akismet_values', $datas );
436 -
437 339 $query_string = _http_build_query( $datas, '', '&' );
438 340 $response = Akismet::http_post( $query_string, 'comment-check' );
439 341
440 342 return ( is_array( $response ) && $response[1] == 'true' );
@@ -444,14 +346,10 @@
444 346 * @since 2.0
445 347 */
446 348 private static function parse_akismet_array( &$datas, $values ) {
447 349 self::add_site_info_to_akismet( $datas );
350 + self::add_user_info_to_akismet( $datas, $values );
448 351 self::add_server_values_to_akismet( $datas );
449 -
450 - self::prepare_values_for_spam_check( $values );
451 -
452 - self::add_user_info_to_akismet( $datas, $values );
453 - self::add_comment_content_to_akismet( $datas, $values );
454 352 }
455 353
456 354 private static function add_site_info_to_akismet( &$datas ) {
457 355 $datas['blog'] = FrmAppHelper::site_url();
@@ -474,127 +372,39 @@
474 372 $datas['user_role'] = Akismet::get_user_roles( $user_info['user_ID'] );
475 373 }
476 374 }
477 375
478 - /**
479 - * Gets user info for Akismet spam check.
480 - *
481 - * @since 5.0.13 Separate code for guest. Handle value of embedded|repeater.
482 - *
483 - * @param array $values Entry values after running through {@see FrmEntryValidate::prepare_values_for_spam_check()}.
484 - * @return array
485 - */
486 376 private static function get_spam_check_user_info( $values ) {
487 - if ( ! is_user_logged_in() ) {
488 - return self::get_spam_check_user_info_for_guest( $values );
489 - }
377 + $datas = array();
490 378
491 - $user = wp_get_current_user();
379 + if ( is_user_logged_in() ) {
380 + $user = wp_get_current_user();
492 381
493 - return array(
494 - 'user_ID' => $user->ID,
495 - 'user_id' => $user->ID,
496 - 'comment_author' => $user->display_name,
497 - 'comment_author_email' => $user->user_email,
498 - 'comment_author_url' => $user->user_url,
499 - );
500 - }
382 + $datas['user_ID'] = $user->ID;
383 + $datas['user_id'] = $user->ID;
384 + $datas['comment_author'] = $user->display_name;
385 + $datas['comment_author_email'] = $user->user_email;
386 + $datas['comment_author_url'] = $user->user_url;
387 + } else {
388 + $datas['comment_author'] = '';
389 + $datas['comment_author_email'] = '';
390 + $datas['comment_author_url'] = '';
501 391
502 - /**
503 - * Gets user info for Akismet spam check for guest.
504 - *
505 - * @since 5.0.13
506 - *
507 - * @param array $values Entry values after flattened.
508 - * @return array
509 - */
510 - private static function get_spam_check_user_info_for_guest( $values ) {
511 - $datas = array(
512 - 'comment_author' => '',
513 - 'comment_author_email' => '',
514 - 'comment_author_url' => '',
515 - 'name_field_ids' => $values['name_field_ids'],
516 - 'missing_keys' => array( 'comment_author_email', 'comment_author_url', 'comment_author' ),
517 - 'frm_duplicated' => array(),
518 - );
519 -
520 - if ( isset( $values['item_meta'] ) ) {
521 - $values = $values['item_meta'];
522 - }
523 -
524 - $values = array_filter( $values );
525 -
526 - self::recursive_add_akismet_guest_info( $datas, $values );
527 - unset( $datas['name_field_ids'] );
528 - unset( $datas['missing_keys'] );
529 -
530 - return $datas;
531 - }
532 -
533 - /**
534 - * Recursive adds akismet guest info.
535 - *
536 - * @since 5.0.13
537 - *
538 - * @param array $datas Guest data.
539 - * @param array $values The values.
540 - * @param int|null $custom_index Custom index (or field ID).
541 - */
542 - private static function recursive_add_akismet_guest_info( &$datas, $values, $custom_index = null ) {
543 - foreach ( $values as $index => $value ) {
544 - if ( ! $datas['missing_keys'] ) {
545 - return; // Found all info.
546 - }
547 -
548 - if ( is_array( $value ) ) {
549 - self::recursive_add_akismet_guest_info( $datas, $value, $index );
550 - continue;
551 - }
552 -
553 - $field_id = ! is_null( $custom_index ) ? $custom_index : $index;
554 - foreach ( $datas['missing_keys'] as $key_index => $key ) {
555 - $found = self::is_akismet_guest_info_value( $key, $value, $field_id, $datas['name_field_ids'] );
556 - if ( $found ) {
557 - $datas[ $key ] = $value;
558 - $datas['frm_duplicated'][] = $field_id;
559 - unset( $datas['missing_keys'][ $key_index ] );
392 + $values = array_filter( $values );
393 + foreach ( $values as $value ) {
394 + if ( ! is_array( $value ) ) {
395 + if ( $datas['comment_author_email'] == '' && strpos( $value, '@' ) && is_email( $value ) ) {
396 + $datas['comment_author_email'] = $value;
397 + } elseif ( $datas['comment_author_url'] == '' && strpos( $value, 'http' ) === 0 ) {
398 + $datas['comment_author_url'] = $value;
399 + } elseif ( $datas['comment_author'] == '' && ! is_numeric( $value ) && strlen( $value ) < 200 ) {
400 + $datas['comment_author'] = $value;
401 + }
560 402 }
561 403 }
562 404 }
563 - }
564 405
565 - /**
566 - * Checks if given value is an akismet guest info.
567 - *
568 - * @since 5.0.13
569 - *
570 - * @param string $key Guest info key.
571 - * @param string $value Value to check.
572 - * @param int $field_id Field ID.
573 - * @param array $name_field_ids Name field IDs.
574 - * @return bool
575 - */
576 - private static function is_akismet_guest_info_value( $key, $value, $field_id, $name_field_ids ) {
577 - if ( ! $value || is_numeric( $value ) ) {
578 - return false;
579 - }
580 -
581 - switch ( $key ) {
582 - case 'comment_author_email':
583 - return strpos( $value, '@' ) && is_email( $value );
584 -
585 - case 'comment_author_url':
586 - return 0 === strpos( $value, 'http' );
587 -
588 - case 'comment_author':
589 - if ( $name_field_ids ) {
590 - // If there is name field in the form, we should always use it as author name.
591 - return in_array( $field_id, $name_field_ids, true );
592 - }
593 - return strlen( $value ) < 200;
594 - }
595 -
596 - return false;
406 + return $datas;
597 407 }
598 408
599 409 private static function add_server_values_to_akismet( &$datas ) {
600 410 foreach ( $_SERVER as $key => $value ) {
@@ -605,203 +415,8 @@
605 415 $datas[ $key ] = $value;
606 416 }
607 417 unset( $key, $value );
608 418 }
609 - }
610 -
611 - /**
612 - * Adds comment content to Akismet data.
613 - *
614 - * @since 5.0.09
615 - *
616 - * @param array $datas The array of values being sent to Akismet.
617 - * @param array $values Entry values.
618 - */
619 - private static function add_comment_content_to_akismet( &$datas, $values ) {
620 - if ( isset( $datas['frm_duplicated'] ) ) {
621 - foreach ( $datas['frm_duplicated'] as $index ) {
622 - if ( isset( $values['item_meta'][ $index ] ) ) {
623 - unset( $values['item_meta'][ $index ] );
624 - } else {
625 - unset( $values[ $index ] );
626 - }
627 - }
628 - unset( $datas['frm_duplicated'] );
629 - }
630 -
631 - self::skip_adding_values_to_akismet( $values );
632 -
633 - $datas['comment_content'] = FrmEntriesHelper::entry_array_to_string( $values );
634 - }
635 -
636 - /**
637 - * Skips adding field values to Akismet.
638 - *
639 - * @since 5.0.09
640 - *
641 - * @param array $values Entry values.
642 - */
643 - private static function skip_adding_values_to_akismet( &$values ) {
644 - $skipped_fields = self::get_akismet_skipped_field_ids( $values );
645 - foreach ( $skipped_fields as $skipped_field ) {
646 - if ( ! isset( $values['item_meta'][ $skipped_field->id ] ) ) {
647 - continue;
648 - }
649 -
650 - if ( self::should_really_skip_field( $skipped_field, $values ) ) {
651 - unset( $values['item_meta'][ $skipped_field->id ] );
652 - if ( isset( $values['item_meta']['other'][ $skipped_field->id ] ) ) {
653 - unset( $values['item_meta']['other'][ $skipped_field->id ] );
654 - }
655 - }
656 - }
657 - }
658 -
659 - /**
660 - * Checks if a skip field should be really skipped.
661 - *
662 - * @since 5.02.04
663 - *
664 - * @param object $field_data Object contains `id` and `options`.
665 - * @param array $values Entry values.
666 - * @return bool
667 - */
668 - private static function should_really_skip_field( $field_data, $values ) {
669 - if ( empty( $field_data->options ) ) { // This is skipped field types.
670 - return true;
671 - }
672 -
673 - FrmAppHelper::unserialize_or_decode( $field_data->options );
674 - if ( ! $field_data->options ) { // Check if an error happens when unserializing, or empty options.
675 - return true;
676 - }
677 -
678 - end( $field_data->options );
679 - $last_key = key( $field_data->options );
680 -
681 - // If a choice field has no Other option.
682 - if ( is_numeric( $last_key ) || 0 !== strpos( $last_key, 'other_' ) ) {
683 - return true;
684 - }
685 -
686 - // If a choice field has Other option, but Other is not selected.
687 - if ( empty( $values['item_meta']['other'][ $field_data->id ] ) ) {
688 - return true;
689 - }
690 -
691 - // Check if submitted value is same as one of field option.
692 - foreach ( $field_data->options as $option ) {
693 - $option_value = ! is_array( $option ) ? $option : ( isset( $option['value'] ) ? $option['value'] : '' );
694 - if ( $values['item_meta']['other'][ $field_data->id ] === $option_value ) {
695 - return true;
696 - }
697 - }
698 -
699 - return false;
700 - }
701 -
702 - /**
703 - * Gets field IDs that are skipped from sending to Akismet spam check.
704 - *
705 - * @since 5.0.09
706 - * @since 5.0.13 Move out get_all_form_ids_and_flatten_meta() call and get `form_ids` from `$values`.
707 - * @since 5.2.04 This method returns array of object contains `id` and `options` instead of array of `id` only.
708 - *
709 - * @param array $values Entry values after running through {@see FrmEntryValidate::prepare_values_for_spam_check()}.
710 - * @return array
711 - */
712 - private static function get_akismet_skipped_field_ids( $values ) {
713 - if ( empty( $values['form_ids'] ) ) {
714 - return array();
715 - }
716 -
717 - $skipped_types = array( 'divider', 'form', 'hidden', 'user_id', 'file', 'date', 'time', 'scale', 'star', 'range', 'toggle', 'data', 'lookup', 'likert', 'nps' );
718 - $has_other_types = array( 'radio', 'checkbox', 'select' );
719 -
720 - $where = array(
721 - array(
722 - 'form_id' => $values['form_ids'],
723 - 'type' => array_merge( $skipped_types, $has_other_types ),
724 - ),
725 - );
726 -
727 - return FrmDb::get_results( 'frm_fields', $where, 'id,options' );
728 - }
729 -
730 - /**
731 - * Prepares values array for spam check.
732 - *
733 - * @since 5.0.13
734 - *
735 - * @param array $values Entry values.
736 - */
737 - private static function prepare_values_for_spam_check( &$values ) {
738 - $form_ids = self::get_all_form_ids_and_flatten_meta( $values );
739 - $values['form_ids'] = $form_ids;
740 - }
741 -
742 - /**
743 - * Gets all form IDs (include child form IDs) and flatten item_meta array. Used for skipping values sent to Akismet.
744 - * This also removes some unused data from the item_meta.
745 - *
746 - * @since 5.0.09
747 - * @since 5.0.13 Convert name field value to string.
748 - *
749 - * @param array $values Entry values.
750 - * @return array Form IDs.
751 - */
752 - private static function get_all_form_ids_and_flatten_meta( &$values ) {
753 - $values['name_field_ids'] = array();
754 -
755 - // Blacklist check for File field in the old version doesn't contain `form_id`.
756 - $form_ids = isset( $values['form_id'] ) ? array( absint( $values['form_id'] ) ) : array();
757 - foreach ( $values['item_meta'] as $field_id => $value ) {
758 - if ( ! is_numeric( $field_id ) ) { // Maybe `other`.
759 - continue;
760 - }
761 -
762 - // Convert name array to string.
763 - if ( isset( $value['first'] ) && isset( $value['last'] ) ) {
764 - $values['item_meta'][ $field_id ] = trim( implode( ' ', $value ) );
765 - $values['name_field_ids'][] = $field_id;
766 - continue;
767 - }
768 -
769 - if ( ! is_array( $value ) || empty( $value['form'] ) ) {
770 - continue;
771 - }
772 -
773 - $form_ids[] = absint( $value['form'] );
774 -
775 - foreach ( $value as $subindex => $subvalue ) {
776 - if ( ! is_numeric( $subindex ) || ! is_array( $subvalue ) ) {
777 - continue;
778 - }
779 -
780 - foreach ( $subvalue as $subsubindex => $subsubvalue ) {
781 - if ( ! $subsubvalue ) {
782 - continue;
783 - }
784 -
785 - if ( ! isset( $values['item_meta'][ $subsubindex ] ) ) {
786 - $values['item_meta'][ $subsubindex ] = array();
787 - }
788 -
789 - // Convert name array to string.
790 - if ( isset( $subsubvalue['first'] ) && isset( $subsubvalue['last'] ) ) {
791 - $subsubvalue = trim( implode( ' ', $subsubvalue ) );
792 -
793 - $values['name_field_ids'][] = $subsubindex;
794 - }
795 -
796 - $values['item_meta'][ $subsubindex ][] = $subsubvalue;
797 - }
798 - }
799 -
800 - unset( $values['item_meta'][ $field_id ] );
801 - }
802 -
803 - return $form_ids;
804 419 }
805 420
806 421 /**
807 422 * @deprecated 3.0