| @@ -210,9 +210,9 @@ | ||
| 210 | 210 | |
| 211 | 211 | if ( $new_val !== $value ) { |
| 212 | 212 | $new_values[ $key ] = $new_val; |
| 213 | 213 | } |
| 214 | - } | |
| 214 | + }//end foreach | |
| 215 | 215 | |
| 216 | 216 | if ( ! empty( $new_values ) ) { |
| 217 | 217 | FrmField::update( $field['id'], $new_values ); |
| 218 | 218 | } |
| @@ -276,9 +276,9 @@ | ||
| 276 | 276 | if ( ! isset( $values['options'] ) ) { |
| 277 | 277 | return $new_values; |
| 278 | 278 | } |
| 279 | 279 | |
| 280 | - $options = isset( $values['options'] ) ? (array) $values['options'] : array(); | |
| 280 | + $options = ! empty( $values['options'] ) ? (array) $values['options'] : array(); | |
| 281 | 281 | FrmFormsHelper::fill_form_options( $options, $values ); |
| 282 | 282 | |
| 283 | 283 | $options['custom_style'] = isset( $values['options']['custom_style'] ) ? $values['options']['custom_style'] : 0; |
| 284 | 284 | $options['before_html'] = isset( $values['options']['before_html'] ) ? $values['options']['before_html'] : FrmFormsHelper::get_default_html( 'before' ); |
| @@ -348,11 +348,12 @@ | ||
| 348 | 348 | continue; |
| 349 | 349 | } |
| 350 | 350 | } |
| 351 | 351 | |
| 352 | - //updating the form | |
| 352 | + // Updating the form. | |
| 353 | 353 | $update_options = FrmFieldsHelper::get_default_field_options_from_field( $field ); |
| 354 | - unset( $update_options['custom_html'] ); // don't check for POST html | |
| 354 | + // Don't check for POST html. | |
| 355 | + unset( $update_options['custom_html'] ); | |
| 355 | 356 | $update_options = apply_filters( 'frm_field_options_to_update', $update_options ); |
| 356 | 357 | |
| 357 | 358 | foreach ( $update_options as $opt => $default ) { |
| 358 | 359 | $field->field_options[ $opt ] = isset( $values['field_options'][ $opt . '_' . $field_id ] ) ? $values['field_options'][ $opt . '_' . $field_id ] : $default; |
| @@ -376,13 +377,14 @@ | ||
| 376 | 377 | } |
| 377 | 378 | } |
| 378 | 379 | |
| 379 | 380 | self::prepare_field_update_values( $field, $values, $new_field ); |
| 381 | + self::maybe_update_max_option( $field, $values, $new_field ); | |
| 380 | 382 | |
| 381 | 383 | FrmField::update( $field_id, $new_field ); |
| 382 | 384 | |
| 383 | 385 | FrmField::delete_form_transient( $field->form_id ); |
| 384 | - } | |
| 386 | + }//end foreach | |
| 385 | 387 | self::clear_form_cache(); |
| 386 | 388 | |
| 387 | 389 | return $values; |
| 388 | 390 | } |
| @@ -387,8 +389,33 @@ | ||
| 387 | 389 | return $values; |
| 388 | 390 | } |
| 389 | 391 | |
| 390 | 392 | /** |
| 393 | + * Resets the 'max' option of a field when changing paragraph field type to other field types like text, email etc. | |
| 394 | + * | |
| 395 | + * @since 6.7 | |
| 396 | + * | |
| 397 | + * @param array $field | |
| 398 | + * @param array $values | |
| 399 | + * @param array $new_field | |
| 400 | + * @return void | |
| 401 | + */ | |
| 402 | + private static function maybe_update_max_option( $field, $values, &$new_field ) { | |
| 403 | + if ( $field->type === 'textarea' && | |
| 404 | + ! empty( $values['field_options'][ 'type_' . $field->id ] ) && | |
| 405 | + in_array( $values['field_options'][ 'type_' . $field->id ], array( 'text', 'email', 'url', 'password', 'phone' ), true ) ) { | |
| 406 | + | |
| 407 | + $new_field['field_options']['max'] = ''; | |
| 408 | + | |
| 409 | + /** | |
| 410 | + * Update posted field setting so that new 'max' option is displayed after form is saved and page reloads. | |
| 411 | + * FrmFieldsHelper::fill_default_field_opts populates field options by calling self::get_posted_field_setting. | |
| 412 | + */ | |
| 413 | + $_POST['field_options'][ 'max_' . $field->id ] = ''; | |
| 414 | + } | |
| 415 | + } | |
| 416 | + | |
| 417 | + /** | |
| 391 | 418 | * @param string $opt |
| 392 | 419 | * @param mixed $value |
| 393 | 420 | * @return void |
| 394 | 421 | */ |
| @@ -428,9 +455,10 @@ | ||
| 428 | 455 | private static function sanitize_calc( $value ) { |
| 429 | 456 | if ( false !== strpos( $value, '<' ) ) { |
| 430 | 457 | $value = self::normalize_calc_spaces( $value ); |
| 431 | 458 | } |
| 432 | - $allow = array( '<= ', ' >=' ); // Allow <= and >= | |
| 459 | + // Allow <= and >=. | |
| 460 | + $allow = array( '<= ', ' >=' ); | |
| 433 | 461 | $temp = array( '< = ', ' > =' ); |
| 434 | 462 | $value = str_replace( $allow, $temp, $value ); |
| 435 | 463 | $value = strip_tags( $value ); |
| 436 | 464 | $value = str_replace( $temp, $allow, $value ); |
| @@ -501,9 +529,9 @@ | ||
| 501 | 529 | * Get a list of all form settings that should be translated |
| 502 | 530 | * on a multilingual site. |
| 503 | 531 | * |
| 504 | 532 | * @since 3.06.01 |
| 505 | - * @param object $form - The form object | |
| 533 | + * @param object $form The form object. | |
| 506 | 534 | */ |
| 507 | 535 | public static function translatable_strings( $form ) { |
| 508 | 536 | $strings = array( |
| 509 | 537 | 'name', |
| @@ -520,8 +548,9 @@ | ||
| 520 | 548 | return apply_filters( 'frm_form_strings', $strings, $form ); |
| 521 | 549 | } |
| 522 | 550 | |
| 523 | 551 | /** |
| 552 | + * @param int $id | |
| 524 | 553 | * @param string $status |
| 525 | 554 | * |
| 526 | 555 | * @return int|boolean |
| 527 | 556 | */ |
| @@ -650,9 +679,9 @@ | ||
| 650 | 679 | */ |
| 651 | 680 | public static function scheduled_delete( $delete_timestamp = '' ) { |
| 652 | 681 | global $wpdb; |
| 653 | 682 | |
| 654 | - $trash_forms = FrmDb::get_results( $wpdb->prefix . 'frm_forms', array( 'status' => 'trash' ), 'id, options' ); | |
| 683 | + $trash_forms = FrmDb::get_results( $wpdb->prefix . 'frm_forms', array( 'status' => 'trash' ), 'id, parent_form_id, options' ); | |
| 655 | 684 | |
| 656 | 685 | if ( ! $trash_forms ) { |
| 657 | 686 | return 0; |
| 658 | 687 | } |
| @@ -665,9 +694,11 @@ | ||
| 665 | 694 | foreach ( $trash_forms as $form ) { |
| 666 | 695 | FrmAppHelper::unserialize_or_decode( $form->options ); |
| 667 | 696 | if ( ! isset( $form->options['trash_time'] ) || $form->options['trash_time'] < $delete_timestamp ) { |
| 668 | 697 | self::destroy( $form->id ); |
| 669 | - $count ++; | |
| 698 | + if ( empty( $form->parent_form_id ) ) { | |
| 699 | + $count ++; | |
| 700 | + } | |
| 670 | 701 | } |
| 671 | 702 | |
| 672 | 703 | unset( $form ); |
| 673 | 704 | } |
| @@ -687,10 +718,12 @@ | ||
| 687 | 718 | } |
| 688 | 719 | |
| 689 | 720 | $query_key = is_numeric( $id ) ? 'id' : 'form_key'; |
| 690 | 721 | $r = FrmDb::get_var( 'frm_forms', array( $query_key => $id ), 'name' ); |
| 691 | - $r = stripslashes( $r ); | |
| 692 | 722 | |
| 723 | + // An empty form name can result in a null value. | |
| 724 | + $r = is_null( $r ) ? '' : stripslashes( $r ); | |
| 725 | + | |
| 693 | 726 | return $r; |
| 694 | 727 | } |
| 695 | 728 | |
| 696 | 729 | /** |
| @@ -788,9 +821,9 @@ | ||
| 788 | 821 | $results = FrmDb::get_results( 'frm_forms', $where, '*', compact( 'order_by', 'limit' ) ); |
| 789 | 822 | } else { |
| 790 | 823 | global $wpdb; |
| 791 | 824 | |
| 792 | - // the query has already been prepared if this is not an array | |
| 825 | + // The query has already been prepared if this is not an array. | |
| 793 | 826 | $query = 'SELECT * FROM ' . $wpdb->prefix . 'frm_forms' . FrmDb::prepend_and_or_where( ' WHERE ', $where ) . FrmDb::esc_order( $order_by ) . FrmDb::esc_limit( $limit ); |
| 794 | 827 | $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
| 795 | 828 | } |
| 796 | 829 | |
| @@ -936,9 +969,9 @@ | ||
| 936 | 969 | $values['posted_form_id'] = FrmAppHelper::get_param( 'form', '', 'get', 'absint' ); |
| 937 | 970 | } |
| 938 | 971 | |
| 939 | 972 | if ( $form->id == $values['posted_form_id'] ) { |
| 940 | - //if there are two forms on the same page, make sure not to submit both | |
| 973 | + // If there are two forms on the same page, make sure not to submit both. | |
| 941 | 974 | foreach ( $default_values as $var => $default ) { |
| 942 | 975 | if ( $var == 'action' ) { |
| 943 | 976 | $values[ $var ] = FrmAppHelper::get_param( $action_var, $default, 'get', 'sanitize_title' ); |
| 944 | 977 | } else { |
| @@ -1127,8 +1160,50 @@ | ||
| 1127 | 1160 | * @return bool |
| 1128 | 1161 | */ |
| 1129 | 1162 | public static function is_ajax_on( $form ) { |
| 1130 | 1163 | return ! empty( $form->options['ajax_submit'] ); |
| 1164 | + } | |
| 1165 | + | |
| 1166 | + /** | |
| 1167 | + * Get the latest form available. | |
| 1168 | + * | |
| 1169 | + * @since 6.8 | |
| 1170 | + * @return object | |
| 1171 | + */ | |
| 1172 | + public static function get_latest_form() { | |
| 1173 | + | |
| 1174 | + $args = array( | |
| 1175 | + array( | |
| 1176 | + 'or' => 1, | |
| 1177 | + 'parent_form_id' => null, | |
| 1178 | + 'parent_form_id <' => 1, | |
| 1179 | + ), | |
| 1180 | + 'is_template' => 0, | |
| 1181 | + 'status !' => 'trash', | |
| 1182 | + ); | |
| 1183 | + | |
| 1184 | + return self::getAll( $args, 'created_at desc', 1 ); | |
| 1185 | + } | |
| 1186 | + | |
| 1187 | + /** | |
| 1188 | + * Count and return total forms. | |
| 1189 | + * | |
| 1190 | + * @since 6.8 | |
| 1191 | + * @return int | |
| 1192 | + */ | |
| 1193 | + public static function get_forms_count() { | |
| 1194 | + | |
| 1195 | + $args = array( | |
| 1196 | + array( | |
| 1197 | + 'or' => 1, | |
| 1198 | + 'parent_form_id' => null, | |
| 1199 | + 'parent_form_id <' => 1, | |
| 1200 | + ), | |
| 1201 | + 'is_template' => 0, | |
| 1202 | + 'status !' => 'trash', | |
| 1203 | + ); | |
| 1204 | + | |
| 1205 | + return FrmDb::get_count( 'frm_forms', $args ); | |
| 1131 | 1206 | } |
| 1132 | 1207 | |
| 1133 | 1208 | /** |
| 1134 | 1209 | * @deprecated 2.03.05 This is still referenced in a few add ons (API, locations). |