← All changes
|
front-end/default-fields/upload/upload_helper_functions.php
+196
-62
3.16.1
→
4.0.3
View file →
| @@ -1,51 +1,34 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | // Exit if accessed directly |
| 3 | 3 | if ( ! defined( 'ABSPATH' ) ) exit; |
| 4 | 4 | |
| 5 | -/* Set up upload field for frontend */ | |
| 6 | -/* overwrite the two functions for when an upload is made from the frontend so they don't check for a logged in user */ | |
| 7 | -if( strpos( wp_get_referer(), 'wp-admin' ) === false && isset( $_REQUEST['action'] ) && 'upload-attachment' == $_REQUEST['action'] ){ | |
| 8 | - | |
| 9 | - if( isset( $_REQUEST['wppb_upload'] ) && 'true' == $_REQUEST['wppb_upload'] && | |
| 10 | - isset( $_REQUEST['meta_name'] ) && wppb_check_that_field_is_defined( sanitize_text_field( $_REQUEST['meta_name'] ), array( 'Avatar', 'Upload' ) ) ){ | |
| 11 | - | |
| 12 | - if( !function_exists( 'check_ajax_referer' ) ){ | |
| 13 | - function check_ajax_referer( ) { | |
| 14 | - return true; | |
| 15 | - } | |
| 16 | - } | |
| 17 | - | |
| 18 | - if( !function_exists( 'auth_redirect' ) ){ | |
| 19 | - function auth_redirect() { | |
| 20 | - return true; | |
| 21 | - } | |
| 22 | - } | |
| 23 | - | |
| 5 | +/** Simple file input when the field is set to it, or the user cannot upload_files. */ | |
| 6 | +function wppb_use_simple_upload_field( $field ) { | |
| 7 | + if ( ! empty( $field['simple-upload'] ) && $field['simple-upload'] === 'yes' ) { | |
| 8 | + return true; | |
| 24 | 9 | } |
| 25 | 10 | |
| 11 | + return ! current_user_can( 'upload_files' ); | |
| 26 | 12 | } |
| 27 | 13 | |
| 28 | -/* create a fake user with the "upload_posts" capability and assign him to the global $current_user. this is used to bypass the checks for current_user_can('upload_files') in async-upload.php */ | |
| 29 | -add_action( 'current_screen', 'wppb_create_fake_user_when_uploading_and_not_logged_in' ); | |
| 30 | -if( !function_exists( 'wppb_create_fake_user_when_uploading_and_not_logged_in' ) ) { | |
| 31 | - function wppb_create_fake_user_when_uploading_and_not_logged_in() { | |
| 32 | - // don't do anything if this request is coming from the back-end | |
| 33 | - if( !( strpos( wp_get_referer(), 'wp-admin' ) === false ) ) | |
| 34 | - return; | |
| 14 | +/** | |
| 15 | + * Whether this request includes a simple-upload for the field. | |
| 16 | + * Checkout and some payment forms post the hidden attachment ID without $_FILES. | |
| 17 | + */ | |
| 18 | +function wppb_simple_upload_was_submitted( $field, $request_data ) { | |
| 19 | + $meta = wppb_handle_meta_name( $field['meta-name'] ); | |
| 20 | + $file_key = 'simple_upload_' . $meta; | |
| 35 | 21 | |
| 36 | - if ( isset($_REQUEST['action']) && 'upload-attachment' == $_REQUEST['action'] && | |
| 37 | - isset($_REQUEST['wppb_upload']) && 'true' == $_REQUEST['wppb_upload'] && | |
| 38 | - isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( $_REQUEST['_wpnonce'] ), 'media-form' ) && | |
| 39 | - isset( $_REQUEST['meta_name'] ) && wppb_check_that_field_is_defined( sanitize_text_field( $_REQUEST['meta_name'] ), array( 'Avatar', 'Upload' ) ) ) { | |
| 22 | + if ( isset( $_FILES[ $file_key ] ) ) { | |
| 23 | + return true; | |
| 24 | + } | |
| 40 | 25 | |
| 41 | - if ( !is_user_logged_in() || !current_user_can( 'upload_files' ) || !current_user_can( 'edit_posts' ) ) { | |
| 42 | - global $current_user; | |
| 43 | - $current_user = new WP_User( 0, 'frontend_uploader' ); | |
| 44 | - $current_user->allcaps = array( "upload_files" => true, "edit_posts" => true, "edit_others_posts" => true, "edit_pages" => true, "edit_others_pages" => true ); | |
| 45 | - } | |
| 46 | - } | |
| 26 | + if ( isset( $request_data['pay_gate'] ) && in_array( $request_data['pay_gate'], array( 'stripe_connect', 'paypal_connect' ), true ) ) { | |
| 27 | + return true; | |
| 47 | 28 | } |
| 29 | + | |
| 30 | + return array_key_exists( $meta, $request_data ); | |
| 48 | 31 | } |
| 49 | 32 | |
| 50 | 33 | /* for a request of a upload from the frontend and no user is logged in don't query for attachments */ |
| 51 | 34 | add_action( 'after_setup_theme', 'wppb_modify_query_attachements_when_not_logged_in' ); |
| @@ -176,23 +159,20 @@ | ||
| 176 | 159 | $allowed_upload_extensions = str_replace( '.', '', array_map( 'trim', explode( ",", strtolower( $allowed_upload_extensions ) ) ) ); |
| 177 | 160 | } else { |
| 178 | 161 | $allowed = true; |
| 179 | 162 | } |
| 180 | - $allowed_by_wordpress = false; | |
| 181 | - foreach ( $allowed_mime_types as $key => $val ){ | |
| 182 | - if ( $val == $upload[ 'type' ] ){ | |
| 183 | - $possible_extensions = explode( '|', $key ); | |
| 184 | - $allowed_by_wordpress = true; | |
| 185 | - } | |
| 163 | + if ( empty( $upload['tmp_name'] ) || empty( $upload['name'] ) ) { | |
| 164 | + return false; | |
| 186 | 165 | } |
| 187 | - if ( isset( $possible_extensions ) && $allowed_by_wordpress == true ){ | |
| 166 | + | |
| 167 | + $checked = wp_check_filetype_and_ext( $upload['tmp_name'], $upload['name'] ); | |
| 168 | + $detected_type = ! empty( $checked['type'] ) ? $checked['type'] : ''; | |
| 169 | + $detected_ext = ! empty( $checked['ext'] ) ? strtolower( $checked['ext'] ) : ''; | |
| 170 | + $allowed_by_wordpress = ( $detected_type !== '' && in_array( $detected_type, $allowed_mime_types, true ) ); | |
| 171 | + | |
| 172 | + if ( $allowed_by_wordpress && $detected_ext !== '' ) { | |
| 188 | 173 | if ( !isset( $allowed ) ){ |
| 189 | - $allowed = false; | |
| 190 | - foreach ( $allowed_upload_extensions as $extension ){ | |
| 191 | - if ( in_array( $extension, $possible_extensions ) ){ | |
| 192 | - $allowed = true; | |
| 193 | - } | |
| 194 | - } | |
| 174 | + $allowed = in_array( $detected_ext, $allowed_upload_extensions, true ); | |
| 195 | 175 | } |
| 196 | 176 | if ( $upload[ 'size' ] > $limit ){ |
| 197 | 177 | $allowed = false; |
| 198 | 178 | } |
| @@ -255,9 +235,9 @@ | ||
| 255 | 235 | } |
| 256 | 236 | else{ |
| 257 | 237 | $repeater_count = count( $repeater_group ); |
| 258 | 238 | for ( $i = 0; $i < $repeater_count; $i++ ){ |
| 259 | - if ( $repeater_group[ $i ][ 'field' ] == 'Upload' && isset( $repeater_group[ $i ][ 'simple-upload' ] ) && $repeater_group[ $i ][ 'simple-upload' ] == 'yes' && isset( $_REQUEST[ $form_field[ 'meta-name' ] . '_extra_groups_count' ] ) ){ | |
| 239 | + if ( $repeater_group[ $i ][ 'field' ] == 'Upload' && wppb_use_simple_upload_field( $repeater_group[ $i ] ) && isset( $_REQUEST[ $form_field[ 'meta-name' ] . '_extra_groups_count' ] ) ){ | |
| 260 | 240 | $groups = absint( $_REQUEST[ $form_field[ 'meta-name' ] . '_extra_groups_count' ] ); |
| 261 | 241 | for ( $j = 0; $j <= $groups; $j++ ){ |
| 262 | 242 | $name = $repeater_group[ $i ][ 'meta-name' ]; |
| 263 | 243 | if ( $j != 0 ){ |
| @@ -300,16 +280,16 @@ | ||
| 300 | 280 | $thumbnail = wp_get_attachment_image($value, array(80, 80), true); |
| 301 | 281 | $file_name = get_the_title($value); |
| 302 | 282 | $file_type = get_post_mime_type($value); |
| 303 | 283 | $attachment_url = wp_get_attachment_url($value); |
| 304 | - $upload_button .= '<div id="' . esc_attr($upload_input_id) . '_info_container" class="upload-field-details" data-attachment_id="' . $value . '">'; | |
| 284 | + $upload_button .= '<div id="' . esc_attr($upload_input_id) . '_info_container" class="upload-field-details" data-attachment_id="' . esc_attr( $value ) . '">'; | |
| 305 | 285 | $upload_button .= '<div class="file-thumb">'; |
| 306 | - $upload_button .= "<a href='{$attachment_url}' target='_blank' class='wppb-attachment-link'>" . $thumbnail . "</a>"; | |
| 286 | + $upload_button .= "<a href='" . esc_url( $attachment_url ) . "' target='_blank' class='wppb-attachment-link'>" . $thumbnail . "</a>"; | |
| 307 | 287 | $upload_button .= '</div>'; |
| 308 | 288 | $upload_button .= '<p><span class="file-name">'; |
| 309 | - $upload_button .= $file_name; | |
| 289 | + $upload_button .= esc_html( $file_name ); | |
| 310 | 290 | $upload_button .= '</span><span class="file-type">'; |
| 311 | - $upload_button .= $file_type; | |
| 291 | + $upload_button .= esc_html( $file_type ); | |
| 312 | 292 | $upload_button .= '</span>'; |
| 313 | 293 | $upload_button .= '<span class="wppb-remove-upload" tabindex="0">' . apply_filters( 'wppb_upload_button_remove_label', __( 'Remove', 'profile-builder' ) ) . '</span>'; |
| 314 | 294 | $upload_button .= '</p></div>'; |
| 315 | 295 | } |
| @@ -319,11 +299,11 @@ | ||
| 319 | 299 | else{ |
| 320 | 300 | $hide_upload_button = ''; |
| 321 | 301 | } |
| 322 | 302 | |
| 323 | - if ( isset( $field[ 'simple-upload' ] ) && $field[ 'simple-upload' ] == 'yes' ){ | |
| 303 | + if ( wppb_use_simple_upload_field( $field ) ){ | |
| 324 | 304 | //If selected accordingly in form fields, generate a simple upload button |
| 325 | - $upload_button .= '<input type="file" id="upload_' . esc_attr(Wordpress_Creation_Kit_PB::wck_generate_slug($field['meta-name'], $field)) . '_button" class="wppb_simple_upload" name="simple_upload_'. esc_attr( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ) .'"'; | |
| 305 | + $upload_button .= '<input type="file" id="upload_' . esc_attr(Wordpress_Creation_Kit_PB::wck_generate_slug($field['meta-name'], $field)) . '_button" class="wppb_simple_upload" data-field_type="'. esc_attr( $field['field'] ) .'" name="simple_upload_'. esc_attr( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ) .'"'; | |
| 326 | 306 | $upload_button .= $hide_upload_button . '>'; |
| 327 | 307 | $upload_button .= '<p id="p_simple_upload_'. esc_attr(Wordpress_Creation_Kit_PB::wck_generate_slug($field['meta-name'], $field)) .'"></p>'; |
| 328 | 308 | $limit = apply_filters( 'wppb_server_max_upload_size_byte_constant', wppb_return_bytes( ini_get( 'upload_max_filesize' ) ) ); |
| 329 | 309 | $all_fields = apply_filters( 'wppb_form_fields', get_option( 'wppb_manage_fields' ), array( 'context' => 'upload_helper', 'upload_meta_name' => $field[ 'meta-name' ] ) ); |
| @@ -355,9 +335,9 @@ | ||
| 355 | 335 | $allowed_extensions = ''; |
| 356 | 336 | } |
| 357 | 337 | } |
| 358 | 338 | } |
| 359 | - $upload_button .= '<input id="allowed_extensions_simple_upload_'. esc_attr( $upload_input_id ) .'" type="hidden" size="36" name="allowed_extensions_simple_upload_'. esc_attr( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ) .'" value="'. $allowed_extensions .'"/>'; | |
| 339 | + $upload_button .= '<input id="allowed_extensions_simple_upload_'. esc_attr( $upload_input_id ) .'" type="hidden" size="36" name="allowed_extensions_simple_upload_'. esc_attr( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ) .'" value="'. esc_attr( $allowed_extensions ) .'"/>'; | |
| 360 | 340 | $upload_button .= '<input id="size_limit_simple_upload_'. esc_attr( $upload_input_id ) .'" type="hidden" name="size_limit_simple_upload_'. esc_attr( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ) .'" value="'. esc_attr( $limit ) .'"/>'; |
| 361 | 341 | $allowed_mime_types = get_allowed_mime_types(); |
| 362 | 342 | $allowed_types = ''; |
| 363 | 343 | if ( !empty( $allowed_mime_types ) ) { |
| @@ -389,9 +369,9 @@ | ||
| 389 | 369 | |
| 390 | 370 | $upload_button .= '>' . apply_filters( 'wppb_upload_button_select_label', __( 'Upload ', 'profile-builder' ) ) . '</a>'; |
| 391 | 371 | } |
| 392 | 372 | |
| 393 | - $upload_button .= '<input id="'. esc_attr( $upload_input_id ) .'" type="hidden" size="36" name="'. esc_attr( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ) .'" value="'. $input_value .'"/>'; | |
| 373 | + $upload_button .= '<input id="'. esc_attr( $upload_input_id ) .'" type="hidden" size="36" name="'. esc_attr( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ) .'" value="'. esc_attr( wp_unslash( $input_value ) ) .'"/>'; | |
| 394 | 374 | return $upload_button; |
| 395 | 375 | } |
| 396 | 376 | |
| 397 | 377 | /** |
| @@ -427,8 +407,65 @@ | ||
| 427 | 407 | return ''; |
| 428 | 408 | } |
| 429 | 409 | } |
| 430 | 410 | |
| 411 | +/** | |
| 412 | + * Converts a legacy file URL stored in user meta (versions that predate attachment IDs) | |
| 413 | + * into an attachment owned by the user and stores the new ID in its place. | |
| 414 | + * | |
| 415 | + * The URL must resolve to an existing file inside the uploads directory with an allowed | |
| 416 | + * mime type; anything else is discarded. Only call this with a value read from user meta, | |
| 417 | + * never with request data, so that rendering a field cannot persist attacker-controlled input. | |
| 418 | + * | |
| 419 | + * @param string $file_url Legacy file URL read from user meta. | |
| 420 | + * @param array $field Field definition array (must contain 'meta-name'). | |
| 421 | + * @param int $user_id User the attachment and meta belong to. | |
| 422 | + * | |
| 423 | + * @return int|string Attachment ID, or '' when the URL could not be converted. | |
| 424 | + */ | |
| 425 | +function wppb_legacy_file_url_to_attachment( $file_url, $field, $user_id ) { | |
| 426 | + $wp_upload_dir = wp_upload_dir(); | |
| 427 | + $base_dir = realpath( $wp_upload_dir['basedir'] ); | |
| 428 | + $file_path = str_replace( $wp_upload_dir['baseurl'], $wp_upload_dir['basedir'], $file_url ); | |
| 429 | + $file_path = is_file( $file_path ) ? realpath( $file_path ) : false; | |
| 430 | + | |
| 431 | + if ( ! $base_dir || ! $file_path ) { | |
| 432 | + return ''; | |
| 433 | + } | |
| 434 | + | |
| 435 | + $base_dir = trailingslashit( wp_normalize_path( $base_dir ) ); | |
| 436 | + $file_path = wp_normalize_path( $file_path ); | |
| 437 | + | |
| 438 | + if ( strpos( $file_path, $base_dir ) !== 0 ) { | |
| 439 | + return ''; | |
| 440 | + } | |
| 441 | + | |
| 442 | + $file_type = wp_check_filetype( basename( $file_path ), null ); | |
| 443 | + if ( empty( $file_type['type'] ) ) { | |
| 444 | + return ''; | |
| 445 | + } | |
| 446 | + | |
| 447 | + $attachment_id = wp_insert_attachment( array( | |
| 448 | + 'guid' => trailingslashit( $wp_upload_dir['baseurl'] ) . substr( $file_path, strlen( $base_dir ) ), | |
| 449 | + 'post_mime_type' => $file_type['type'], | |
| 450 | + 'post_title' => sanitize_text_field( preg_replace( '/\.[^.]+$/', '', basename( $file_path ) ) ), | |
| 451 | + 'post_content' => '', | |
| 452 | + 'post_status' => 'inherit', | |
| 453 | + 'post_author' => $user_id, | |
| 454 | + ), $file_path ); | |
| 455 | + | |
| 456 | + if ( empty( $attachment_id ) || is_wp_error( $attachment_id ) ) { | |
| 457 | + return ''; | |
| 458 | + } | |
| 459 | + | |
| 460 | + // Make sure that this file is included, as wp_generate_attachment_metadata() depends on it. | |
| 461 | + require_once ABSPATH . 'wp-admin/includes/image.php'; | |
| 462 | + wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file_path ) ); | |
| 463 | + update_user_meta( $user_id, $field['meta-name'], $attachment_id ); | |
| 464 | + | |
| 465 | + return $attachment_id; | |
| 466 | +} | |
| 467 | + | |
| 431 | 468 | // Deferred to plugins_loaded so older Profile Builder Pro versions (which declare |
| 432 | 469 | // wppb_verify_attachment_id unconditionally during their own file load) win the |
| 433 | 470 | // declaration race and our function_exists guard then skips — avoiding a fatal. |
| 434 | 471 | add_action( 'plugins_loaded', 'wppb_register_attachment_ownership_helpers', 20 ); |
| @@ -458,10 +495,18 @@ | ||
| 458 | 495 | // Allow admins to upload files for users |
| 459 | 496 | if ( $is_admin ) { |
| 460 | 497 | return true; |
| 461 | 498 | } |
| 462 | - // Only update if the attachment belongs to the user or has no author (post_author = 0) | |
| 463 | - if ( $attachment->post_author == $user_id || $attachment->post_author == $current_user_id || $attachment->post_author == 0 ) { | |
| 499 | + // The attachment is claimable when it already belongs to the target | |
| 500 | + // user, or to the user performing the request. An author-less | |
| 501 | + // attachment (post_author == 0) is only claimable by an | |
| 502 | + // unauthenticated request (e.g. a visitor registering, whose upload | |
| 503 | + // has no author yet). This prevents an authenticated user from | |
| 504 | + // claiming (IDOR) an author-0 attachment created by someone else's | |
| 505 | + // anonymous/nopriv upload. | |
| 506 | + if ( $attachment->post_author == $user_id | |
| 507 | + || ( $current_user_id && $attachment->post_author == $current_user_id ) | |
| 508 | + || ( 0 === (int) $current_user_id && 0 === (int) $attachment->post_author ) ) { | |
| 464 | 509 | return true; |
| 465 | 510 | } |
| 466 | 511 | } else { |
| 467 | 512 | // If no user ID is provided, check if current user is admin |
| @@ -467,10 +512,13 @@ | ||
| 467 | 512 | // If no user ID is provided, check if current user is admin |
| 468 | 513 | if ( $is_admin ) { |
| 469 | 514 | return true; |
| 470 | 515 | } |
| 471 | - // If no user ID is provided, check if the attachment has no author | |
| 472 | - if ( $attachment->post_author == $current_user_id || $attachment->post_author == 0 ) { | |
| 516 | + // Without an explicit target user, an authenticated user may only | |
| 517 | + // reference an attachment they already own; an author-less | |
| 518 | + // attachment is only claimable by an unauthenticated request. | |
| 519 | + if ( ( $current_user_id && $attachment->post_author == $current_user_id ) | |
| 520 | + || ( 0 === (int) $current_user_id && 0 === (int) $attachment->post_author ) ) { | |
| 473 | 521 | return true; |
| 474 | 522 | } |
| 475 | 523 | } |
| 476 | 524 | } |
| @@ -500,8 +548,94 @@ | ||
| 500 | 548 | update_user_meta( $user_id, $field['meta-name'], '' ); |
| 501 | 549 | } |
| 502 | 550 | } |
| 503 | 551 | } |
| 552 | +} | |
| 553 | + | |
| 554 | +/** | |
| 555 | + * Resolves a simple-upload AJAX `name` parameter to a configured form field. | |
| 556 | + * | |
| 557 | + * @param string $post_name Sanitized value of $_POST['name'] from the AJAX request. | |
| 558 | + * @param string|array $field_type Expected field type(s), e.g. 'Avatar' or 'Upload'. | |
| 559 | + * | |
| 560 | + * @return array|false Field definition array, or false when not found or not simple-upload. | |
| 561 | + */ | |
| 562 | +function wppb_resolve_simple_upload_ajax_field( $post_name, $field_type ) { | |
| 563 | + if ( empty( $post_name ) ) { | |
| 564 | + return false; | |
| 565 | + } | |
| 566 | + | |
| 567 | + $field_types = is_array( $field_type ) ? $field_type : array( $field_type ); | |
| 568 | + $all_fields = apply_filters( 'wppb_form_fields', get_option( 'wppb_manage_fields' ), array( 'context' => 'simple_upload_ajax', 'upload_post_name' => $post_name ) ); | |
| 569 | + | |
| 570 | + if ( empty( $all_fields ) ) { | |
| 571 | + return false; | |
| 572 | + } | |
| 573 | + | |
| 574 | + foreach ( $all_fields as $field ) { | |
| 575 | + if ( ! in_array( $field['field'], $field_types, true ) ) { | |
| 576 | + continue; | |
| 577 | + } | |
| 578 | + if ( ! wppb_use_simple_upload_field( $field ) ) { | |
| 579 | + continue; | |
| 580 | + } | |
| 581 | + | |
| 582 | + $field_slug = str_replace( '-', '_', Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) ); | |
| 583 | + if ( $field_slug === $post_name ) { | |
| 584 | + return $field; | |
| 585 | + } | |
| 586 | + } | |
| 587 | + | |
| 588 | + // The field was not found among the top-level form fields. Repeater fields store | |
| 589 | + // their inner Upload fields in a separate option keyed by the repeater's | |
| 590 | + // meta-name, so those fields are never part of the wppb_manage_fields list scanned | |
| 591 | + // above. Scan the repeater groups as well, otherwise Simple Upload inside a | |
| 592 | + // Repeater field is silently rejected (the lookup fails and the file input clears). | |
| 593 | + return wppb_resolve_simple_upload_ajax_field_in_repeater( $post_name, $field_types, $all_fields ); | |
| 594 | +} | |
| 595 | + | |
| 596 | +/** | |
| 597 | + * Resolves a simple-upload AJAX `name` parameter to an Upload field nested inside a | |
| 598 | + * Repeater field. | |
| 599 | + * | |
| 600 | + * Repeater sub-fields are stored unindexed in an option keyed by the repeater's | |
| 601 | + * meta-name. On the front-end each group posts either "<slug>" (the first group) or | |
| 602 | + * "<slug>_N" (the Nth extra group), where <slug> is the dash-normalized wck slug of | |
| 603 | + * the inner field's meta-name. | |
| 604 | + * | |
| 605 | + * @param string $post_name Sanitized value of $_POST['name'] from the AJAX request. | |
| 606 | + * @param array $field_types Expected field type(s), e.g. array( 'Upload' ). | |
| 607 | + * @param array $all_fields The already-resolved top-level form fields. | |
| 608 | + * | |
| 609 | + * @return array|false Inner field definition array, or false when not found. | |
| 610 | + */ | |
| 611 | +function wppb_resolve_simple_upload_ajax_field_in_repeater( $post_name, $field_types, $all_fields ) { | |
| 612 | + foreach ( $all_fields as $form_field ) { | |
| 613 | + if ( empty( $form_field['field'] ) || $form_field['field'] !== 'Repeater' ) { | |
| 614 | + continue; | |
| 615 | + } | |
| 616 | + | |
| 617 | + $repeater_group = get_option( $form_field['meta-name'], 'not_set' ); | |
| 618 | + if ( $repeater_group === 'not_set' || ! is_array( $repeater_group ) ) { | |
| 619 | + continue; | |
| 620 | + } | |
| 621 | + | |
| 622 | + foreach ( $repeater_group as $inner_field ) { | |
| 623 | + if ( empty( $inner_field['field'] ) || ! in_array( $inner_field['field'], $field_types, true ) ) { | |
| 624 | + continue; | |
| 625 | + } | |
| 626 | + if ( ! wppb_use_simple_upload_field( $inner_field ) ) { | |
| 627 | + continue; | |
| 628 | + } | |
| 629 | + | |
| 630 | + $base_slug = str_replace( '-', '_', Wordpress_Creation_Kit_PB::wck_generate_slug( $inner_field['meta-name'], $inner_field ) ); | |
| 631 | + if ( $base_slug === $post_name || preg_match( '/^' . preg_quote( $base_slug, '/' ) . '_[0-9]+$/', $post_name ) ) { | |
| 632 | + return $inner_field; | |
| 633 | + } | |
| 634 | + } | |
| 635 | + } | |
| 636 | + | |
| 637 | + return false; | |
| 504 | 638 | } |
| 505 | 639 | |
| 506 | 640 | function wppb_check_that_field_is_defined( $meta_name, $field_types = array() ){ |
| 507 | 641 | |