PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 4.0.3
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v4.0.3
4.0.3 4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 341 releases
← All changes | front-end/default-fields/upload/upload_helper_functions.php +94 -78 4.0.0 → 4.0.3 View file →
@@ -1,66 +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 -/* Front-end Avatar/Upload async-upload bypass when the real user lacks upload caps.
29 - * Guests use WP_User(0) (author-less until registration). Logged-in users keep their ID
30 - * and only gain temporary caps so the attachment is owned by them (see wppb_verify_attachment_id). */
31 -add_action( 'current_screen', 'wppb_create_fake_user_when_uploading_and_not_logged_in' );
32 -if( !function_exists( 'wppb_create_fake_user_when_uploading_and_not_logged_in' ) ) {
33 - function wppb_create_fake_user_when_uploading_and_not_logged_in() {
34 - // don't do anything if this request is coming from the back-end
35 - if( !( strpos( wp_get_referer(), 'wp-admin' ) === false ) )
36 - 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;
37 21
38 - if ( isset($_REQUEST['action']) && 'upload-attachment' == $_REQUEST['action'] &&
39 - isset($_REQUEST['wppb_upload']) && 'true' == $_REQUEST['wppb_upload'] &&
40 - isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( $_REQUEST['_wpnonce'] ), 'media-form' ) &&
41 - 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 + }
42 25
43 - if ( !is_user_logged_in() || !current_user_can( 'upload_files' ) || !current_user_can( 'edit_posts' ) ) {
44 - global $current_user;
26 + if ( isset( $request_data['pay_gate'] ) && in_array( $request_data['pay_gate'], array( 'stripe_connect', 'paypal_connect' ), true ) ) {
27 + return true;
28 + }
45 29
46 - $upload_caps = array(
47 - 'upload_files' => true,
48 - 'edit_posts' => true,
49 - 'edit_others_posts' => true,
50 - 'edit_pages' => true,
51 - 'edit_others_pages' => true,
52 - );
53 -
54 - if ( is_user_logged_in() ) {
55 - $current_user->allcaps = array_merge( (array) $current_user->allcaps, $upload_caps );
56 - } else {
57 - $current_user = new WP_User( 0, 'frontend_uploader' );
58 - $current_user->allcaps = $upload_caps;
59 - }
60 - }
61 - }
62 - }
30 + return array_key_exists( $meta, $request_data );
63 31 }
64 32
65 33 /* for a request of a upload from the frontend and no user is logged in don't query for attachments */
66 34 add_action( 'after_setup_theme', 'wppb_modify_query_attachements_when_not_logged_in' );
@@ -191,23 +159,20 @@
191 159 $allowed_upload_extensions = str_replace( '.', '', array_map( 'trim', explode( ",", strtolower( $allowed_upload_extensions ) ) ) );
192 160 } else {
193 161 $allowed = true;
194 162 }
195 - $allowed_by_wordpress = false;
196 - foreach ( $allowed_mime_types as $key => $val ){
197 - if ( $val == $upload[ 'type' ] ){
198 - $possible_extensions = explode( '|', $key );
199 - $allowed_by_wordpress = true;
200 - }
163 + if ( empty( $upload['tmp_name'] ) || empty( $upload['name'] ) ) {
164 + return false;
201 165 }
202 - 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 !== '' ) {
203 173 if ( !isset( $allowed ) ){
204 - $allowed = false;
205 - foreach ( $allowed_upload_extensions as $extension ){
206 - if ( in_array( $extension, $possible_extensions ) ){
207 - $allowed = true;
208 - }
209 - }
174 + $allowed = in_array( $detected_ext, $allowed_upload_extensions, true );
210 175 }
211 176 if ( $upload[ 'size' ] > $limit ){
212 177 $allowed = false;
213 178 }
@@ -270,9 +235,9 @@
270 235 }
271 236 else{
272 237 $repeater_count = count( $repeater_group );
273 238 for ( $i = 0; $i < $repeater_count; $i++ ){
274 - 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' ] ) ){
275 240 $groups = absint( $_REQUEST[ $form_field[ 'meta-name' ] . '_extra_groups_count' ] );
276 241 for ( $j = 0; $j <= $groups; $j++ ){
277 242 $name = $repeater_group[ $i ][ 'meta-name' ];
278 243 if ( $j != 0 ){
@@ -315,16 +280,16 @@
315 280 $thumbnail = wp_get_attachment_image($value, array(80, 80), true);
316 281 $file_name = get_the_title($value);
317 282 $file_type = get_post_mime_type($value);
318 283 $attachment_url = wp_get_attachment_url($value);
319 - $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 ) . '">';
320 285 $upload_button .= '<div class="file-thumb">';
321 - $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>";
322 287 $upload_button .= '</div>';
323 288 $upload_button .= '<p><span class="file-name">';
324 - $upload_button .= $file_name;
289 + $upload_button .= esc_html( $file_name );
325 290 $upload_button .= '</span><span class="file-type">';
326 - $upload_button .= $file_type;
291 + $upload_button .= esc_html( $file_type );
327 292 $upload_button .= '</span>';
328 293 $upload_button .= '<span class="wppb-remove-upload" tabindex="0">' . apply_filters( 'wppb_upload_button_remove_label', __( 'Remove', 'profile-builder' ) ) . '</span>';
329 294 $upload_button .= '</p></div>';
330 295 }
@@ -334,9 +299,9 @@
334 299 else{
335 300 $hide_upload_button = '';
336 301 }
337 302
338 - if ( isset( $field[ 'simple-upload' ] ) && $field[ 'simple-upload' ] == 'yes' ){
303 + if ( wppb_use_simple_upload_field( $field ) ){
339 304 //If selected accordingly in form fields, generate a simple upload button
340 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 ) ) .'"';
341 306 $upload_button .= $hide_upload_button . '>';
342 307 $upload_button .= '<p id="p_simple_upload_'. esc_attr(Wordpress_Creation_Kit_PB::wck_generate_slug($field['meta-name'], $field)) .'"></p>';
@@ -442,8 +407,65 @@
442 407 return '';
443 408 }
444 409 }
445 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 +
446 468 // Deferred to plugins_loaded so older Profile Builder Pro versions (which declare
447 469 // wppb_verify_attachment_id unconditionally during their own file load) win the
448 470 // declaration race and our function_exists guard then skips — avoiding a fatal.
449 471 add_action( 'plugins_loaded', 'wppb_register_attachment_ownership_helpers', 20 );
@@ -552,14 +574,11 @@
552 574 foreach ( $all_fields as $field ) {
553 575 if ( ! in_array( $field['field'], $field_types, true ) ) {
554 576 continue;
555 577 }
556 - if ( ! isset( $field['simple-upload'] ) || $field['simple-upload'] !== 'yes' ) {
578 + if ( ! wppb_use_simple_upload_field( $field ) ) {
557 579 continue;
558 580 }
559 - if ( isset( $field['woocommerce-checkout-field'] ) && $field['woocommerce-checkout-field'] === 'Yes' ) {
560 - continue;
561 - }
562 581
563 582 $field_slug = str_replace( '-', '_', Wordpress_Creation_Kit_PB::wck_generate_slug( $field['meta-name'], $field ) );
564 583 if ( $field_slug === $post_name ) {
565 584 return $field;
@@ -603,12 +622,9 @@
603 622 foreach ( $repeater_group as $inner_field ) {
604 623 if ( empty( $inner_field['field'] ) || ! in_array( $inner_field['field'], $field_types, true ) ) {
605 624 continue;
606 625 }
607 - if ( ! isset( $inner_field['simple-upload'] ) || $inner_field['simple-upload'] !== 'yes' ) {
608 - continue;
609 - }
610 - if ( isset( $inner_field['woocommerce-checkout-field'] ) && $inner_field['woocommerce-checkout-field'] === 'Yes' ) {
626 + if ( ! wppb_use_simple_upload_field( $inner_field ) ) {
611 627 continue;
612 628 }
613 629
614 630 $base_slug = str_replace( '-', '_', Wordpress_Creation_Kit_PB::wck_generate_slug( $inner_field['meta-name'], $inner_field ) );