From 30225fc70f3899bd94382a4b998fa113b7eccf07 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Thu, 18 Apr 2024 14:36:44 -0700 Subject: [PATCH 01/11] Remove use of nested filters. Add params to wp_handle_upload() and wp_upload_bits() instead. --- src/wp-admin/includes/file.php | 10 ++- src/wp-includes/fonts.php | 81 ++++++++++--------- src/wp-includes/functions.php | 29 ++++--- .../class-wp-rest-font-faces-controller.php | 8 +- .../fonts/font-library/fontLibraryHooks.php | 9 ++- .../tests/fonts/font-library/wpFontsDir.php | 8 -- 6 files changed, 82 insertions(+), 63 deletions(-) diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 75c741541ae4c..6d48d87bbcf79 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -786,6 +786,9 @@ function validate_file_to_edit( $file, $allowed_files = array() ) { * @type bool $test_size Whether to test that the file size is greater than zero bytes. * @type bool $test_type Whether to test that the mime type of the file is as expected. * @type string[] $mimes Array of allowed mime types keyed by their file extension regex. + * @type string[] $upload_dir Array of the uploads directory data as returned by + * {@see wp_upload_dir()} or {@see wp_font_dir()}. If not set the function + * will use {@see wp_upload_dir()}. * } * @param string $time Time formatted in 'yyyy/mm'. * @param string $action Expected value for `$_POST['action']`. @@ -972,11 +975,16 @@ function wp_handle_upload_error( &$file, $message ) { $type = ''; } + if ( isset( $overrides['upload_dir'] ) ) { + $uploads = $overrides['upload_dir']; + } else { + $uploads = wp_upload_dir( $time ); + } + /* * A writable uploads dir will pass this test. Again, there's no point * overriding this one. */ - $uploads = wp_upload_dir( $time ); if ( ! ( $uploads && false === $uploads['error'] ) ) { return call_user_func_array( $upload_error_handler, array( &$file, $uploads['error'] ) ); } diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 4806662160b81..609cbf329586d 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -126,44 +126,17 @@ function wp_get_font_dir() { * } */ function wp_font_dir( $create_dir = true ) { - /* - * Allow extenders to manipulate the font directory consistently. - * - * Ensures the upload_dir filter is fired both when calling this function - * directly and when the upload directory is filtered in the Font Face - * REST API endpoint. - */ - add_filter( 'upload_dir', '_wp_filter_font_directory' ); - $font_dir = wp_upload_dir( null, $create_dir, false ); - remove_filter( 'upload_dir', '_wp_filter_font_directory' ); - return $font_dir; -} - -/** - * A callback function for use in the {@see 'upload_dir'} filter. - * - * This function is intended for internal use only and should not be used by plugins and themes. - * Use wp_get_font_dir() instead. - * - * @since 6.5.0 - * @access private - * - * @param string $font_dir The font directory. - * @return string The modified font directory. - */ -function _wp_filter_font_directory( $font_dir ) { - if ( doing_filter( 'font_dir' ) ) { - // Avoid an infinite loop. - return $font_dir; - } + // This will also create the /uploads directory if it doesn't exist and $create_dir is true. + $upload_dir = wp_upload_dir( null, $create_dir, false ); + // Default fonts directory settings. $font_dir = array( - 'path' => untrailingslashit( $font_dir['basedir'] ) . '/fonts', - 'url' => untrailingslashit( $font_dir['baseurl'] ) . '/fonts', + 'path' => untrailingslashit( $upload_dir['basedir'] ) . '/fonts', + 'url' => untrailingslashit( $upload_dir['baseurl'] ) . '/fonts', 'subdir' => '', - 'basedir' => untrailingslashit( $font_dir['basedir'] ) . '/fonts', - 'baseurl' => untrailingslashit( $font_dir['baseurl'] ) . '/fonts', - 'error' => false, + 'basedir' => untrailingslashit( $upload_dir['basedir'] ) . '/fonts', + 'baseurl' => untrailingslashit( $upload_dir['baseurl'] ) . '/fonts', + 'error' => $upload_dir['error'], ); /** @@ -184,7 +157,43 @@ function _wp_filter_font_directory( $font_dir ) { * @type string|false $error False or error message. * } */ - return apply_filters( 'font_dir', $font_dir ); + $font_dir = apply_filters( 'font_dir', $font_dir ); + + // Do not attempt to create the /fonts directory if there was an error in wp_upload_dir() or after the 'font_dir' filter. + if ( ! empty( $font_dir['error'] ) ) { + return $font_dir; + } + + if ( $create_dir ) { + $created = wp_mkdir_p( $font_dir['basedir'] ); + + if ( false === $created ) { + $font_dir['error'] = sprintf( + /* translators: %s: Directory path. */ + __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), + esc_html( $font_dir['basedir'] ) + ); + } + } + + return $font_dir; +} + +/** + * A callback function for use in the {@see 'upload_dir'} filter. + * + * This function is intended for internal use only and should not be used by plugins and themes. + * + * @since 6.5.0 + * @deprecated 6.6.0 + * @access private + * + * @param string $font_dir The font directory path. + * @return string The font directory path. + */ +function _wp_filter_font_directory( $font_dir ) { + _deprecated_function( __FUNCTION__, '6.6.0' ); + return $font_dir; } /** diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index d7cc00672bce3..89eeead5a7dc8 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -2872,6 +2872,9 @@ function _wp_check_existing_file_names( $filename, $files ) { * @param null|string $deprecated Never used. Set to null. * @param string $bits File content * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null. + * @param string[] $upload_dir Optional. Array of the uploads directory data as returned by + * {@see wp_upload_dir()} or {@see wp_font_dir()}. If not set + * the function will use {@see wp_upload_dir()}. * @return array { * Information about the newly-uploaded file. * @@ -2881,7 +2884,7 @@ function _wp_check_existing_file_names( $filename, $files ) { * @type string|false $error Error message, if there has been an error. * } */ -function wp_upload_bits( $name, $deprecated, $bits, $time = null ) { +function wp_upload_bits( $name, $deprecated, $bits, $time = null, $upload_dir = array() ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.0.0' ); } @@ -2895,10 +2898,12 @@ function wp_upload_bits( $name, $deprecated, $bits, $time = null ) { return array( 'error' => __( 'Sorry, you are not allowed to upload this file type.' ) ); } - $upload = wp_upload_dir( $time ); + if ( empty( $upload_dir ) ) { + $upload_dir = wp_upload_dir( $time ); + } - if ( false !== $upload['error'] ) { - return $upload; + if ( false !== $upload_dir['error'] ) { + return $upload_dir; } /** @@ -2920,18 +2925,18 @@ function wp_upload_bits( $name, $deprecated, $bits, $time = null ) { ) ); if ( ! is_array( $upload_bits_error ) ) { - $upload['error'] = $upload_bits_error; - return $upload; + $upload_dir['error'] = $upload_bits_error; + return $upload_dir; } - $filename = wp_unique_filename( $upload['path'], $name ); + $filename = wp_unique_filename( $upload_dir['path'], $name ); - $new_file = $upload['path'] . "/$filename"; + $new_file = $upload_dir['path'] . "/$filename"; if ( ! wp_mkdir_p( dirname( $new_file ) ) ) { - if ( str_starts_with( $upload['basedir'], ABSPATH ) ) { - $error_path = str_replace( ABSPATH, '', $upload['basedir'] ) . $upload['subdir']; + if ( str_starts_with( $upload_dir['basedir'], ABSPATH ) ) { + $error_path = str_replace( ABSPATH, '', $upload_dir['basedir'] ) . $upload_dir['subdir']; } else { - $error_path = wp_basename( $upload['basedir'] ) . $upload['subdir']; + $error_path = wp_basename( $upload_dir['basedir'] ) . $upload_dir['subdir']; } $message = sprintf( @@ -2962,7 +2967,7 @@ function wp_upload_bits( $name, $deprecated, $bits, $time = null ) { clearstatcache(); // Compute the URL. - $url = $upload['url'] . "/$filename"; + $url = $upload_dir['url'] . "/$filename"; if ( is_multisite() ) { clean_dirsize_cache( $new_file ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php index c7f72d4ec1d9d..a41418e4cd468 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-font-faces-controller.php @@ -856,8 +856,9 @@ protected function sanitize_src( $value ) { */ protected function handle_font_file_upload( $file ) { add_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); - // Filter the upload directory to return the fonts directory. - add_filter( 'upload_dir', '_wp_filter_font_directory' ); + + // This will create the /fonts directory if it doesn't exist. + $font_dir = wp_font_dir(); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -865,6 +866,8 @@ protected function handle_font_file_upload( $file ) { 'test_form' => false, // Only allow uploading font files for this request. 'mimes' => WP_Font_Utils::get_allowed_font_mime_types(), + // Upload to the /fonts directory + 'upload_dir' => $font_dir, ); // Bypasses is_uploaded_file() when running unit tests. @@ -874,7 +877,6 @@ protected function handle_font_file_upload( $file ) { $uploaded_file = wp_handle_upload( $file, $overrides ); - remove_filter( 'upload_dir', '_wp_filter_font_directory' ); remove_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); return $uploaded_file; diff --git a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php index c288a1ae93845..df400c8a599d0 100644 --- a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php +++ b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -73,13 +73,16 @@ protected function upload_font_file( $font_filename ) { $font_file_path = DIR_TESTDATA . '/fonts/' . $font_filename; add_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); - add_filter( 'upload_dir', '_wp_filter_font_directory' ); + $font_dir = wp_get_font_dir(); + $font_file = wp_upload_bits( $font_filename, null, - file_get_contents( $font_file_path ) + file_get_contents( $font_file_path ), + null, + $font_dir ); - remove_filter( 'upload_dir', '_wp_filter_font_directory' ); + remove_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); return $font_file; diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index 22208ca7b2e26..93d650a21ca42 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -111,14 +111,6 @@ function set_new_values( $defaults ) { * @ticket 60652 */ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { - /* - * Naive filtering of uploads directory to return font directory. - * - * This emulates the approach a plugin developer may take to - * add the filter when extending the font library functionality. - */ - add_filter( 'upload_dir', '_wp_filter_font_directory' ); - add_filter( 'upload_dir', function ( $upload_dir ) { From 1617d8112f506ea86eff82b68882e3f841bffd66 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:49:30 -0700 Subject: [PATCH 02/11] Add $upload_dir as param to the font_dir filter Makes it a bit faster/easier for plugins to reuse the uploads dir for fonts (although it seems as a bad idea to mix them with images/other uploads). --- src/wp-includes/fonts.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 609cbf329586d..a3936367c4dd1 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -156,8 +156,9 @@ function wp_font_dir( $create_dir = true ) { * @type string $baseurl URL path without subdir. * @type string|false $error False or error message. * } + * @param array $upload_dir The uploads directory data as returned by {@see wp_upload_dir()}. */ - $font_dir = apply_filters( 'font_dir', $font_dir ); + $font_dir = apply_filters( 'font_dir', $font_dir, $upload_dir ); // Do not attempt to create the /fonts directory if there was an error in wp_upload_dir() or after the 'font_dir' filter. if ( ! empty( $font_dir['error'] ) ) { From 48339ed8c535e703a4f09a6c4c43f33d09732ef0 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:53:17 -0700 Subject: [PATCH 03/11] Move _wp_filter_font_directory() to deprecated.php --- src/wp-includes/deprecated.php | 17 +++++++++++++++++ src/wp-includes/fonts.php | 17 ----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/deprecated.php b/src/wp-includes/deprecated.php index 155ce0fef0aed..0f2d751c59444 100644 --- a/src/wp-includes/deprecated.php +++ b/src/wp-includes/deprecated.php @@ -6300,3 +6300,20 @@ function block_core_image_ensure_interactivity_dependency() { $wp_scripts->registered['wp-block-image-view']->deps[] = 'wp-interactivity'; } } + +/** + * A callback function for use in the {@see 'upload_dir'} filter. + * + * This function is intended for internal use only and should not be used by plugins and themes. + * + * @since 6.5.0 + * @deprecated 6.6.0 + * @access private + * + * @param string $font_dir The font directory path. + * @return string The font directory path. + */ +function _wp_filter_font_directory( $font_dir ) { + _deprecated_function( __FUNCTION__, '6.6.0' ); + return $font_dir; +} diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index a3936367c4dd1..e899b4deb42a3 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -180,23 +180,6 @@ function wp_font_dir( $create_dir = true ) { return $font_dir; } -/** - * A callback function for use in the {@see 'upload_dir'} filter. - * - * This function is intended for internal use only and should not be used by plugins and themes. - * - * @since 6.5.0 - * @deprecated 6.6.0 - * @access private - * - * @param string $font_dir The font directory path. - * @return string The font directory path. - */ -function _wp_filter_font_directory( $font_dir ) { - _deprecated_function( __FUNCTION__, '6.6.0' ); - return $font_dir; -} - /** * Deletes child font faces when a font family is deleted. * From abc261067ac2a878c71118f371432e7bd2c2dc9d Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Wed, 15 May 2024 17:35:43 -0700 Subject: [PATCH 04/11] Merge remote trunk --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index eab8b127b2025..05d2c63732dbd 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -2871,7 +2871,7 @@ function _wp_check_existing_file_names( $filename, $files ) { * @param string $name Filename. * @param null|string $deprecated Never used. Set to null. * @param string $bits File content - * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null. + * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null. * @param string[] $upload_dir Optional. Array of the uploads directory data as returned by * {@see wp_upload_dir()} or {@see wp_font_dir()}. If not set * the function will use {@see wp_upload_dir()}. From 5c4039b2bcb41d2061e359b529ecab1ae6b93a45 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Fri, 17 May 2024 16:23:21 -0700 Subject: [PATCH 05/11] When creating the fonts dir use $font_dir['path'], not $font_dir['path'], not basedir --- src/wp-includes/fonts.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index b97181a76e65a..e88eaca9ea6b3 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -168,13 +168,13 @@ function wp_font_dir( $create_dir = true ) { } if ( $create_dir ) { - $created = wp_mkdir_p( $font_dir['basedir'] ); + $created = wp_mkdir_p( $font_dir['path'] ); if ( false === $created ) { $font_dir['error'] = sprintf( /* translators: %s: Directory path. */ __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), - esc_html( $font_dir['basedir'] ) + esc_html( $font_dir['path'] ) ); } } From 86612b6e1a65652d9e09d83f7980d32ed7a62160 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Thu, 30 May 2024 15:19:45 -0700 Subject: [PATCH 06/11] Update src/wp-includes/fonts.php Reset the error message that may be returned by `wp_pload_dir()` but honor it if it is set by a plugin using the `font_fir` filter. Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> --- src/wp-includes/fonts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index e88eaca9ea6b3..ace2ee0c6149d 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -138,7 +138,7 @@ function wp_font_dir( $create_dir = true ) { 'subdir' => '', 'basedir' => untrailingslashit( $upload_dir['basedir'] ) . '/fonts', 'baseurl' => untrailingslashit( $upload_dir['baseurl'] ) . '/fonts', - 'error' => $upload_dir['error'], + 'error' => false, ); /** From 8d9e9d8e6799c621ec95114749203c5121cd4341 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Thu, 30 May 2024 15:22:48 -0700 Subject: [PATCH 07/11] Update src/wp-includes/fonts.php Do not attempt to create the WP uploads directory even if it doesn't exist yet. It will be created by `wp_mkdir_p()` if needed. Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> --- src/wp-includes/fonts.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index ace2ee0c6149d..6aad89f650f49 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -128,8 +128,8 @@ function wp_get_font_dir() { * } */ function wp_font_dir( $create_dir = true ) { - // This will also create the /uploads directory if it doesn't exist and $create_dir is true. - $upload_dir = wp_upload_dir( null, $create_dir, false ); + // Get base uploads directory. + $upload_dir = wp_upload_dir( null, false, false ); // Default fonts directory settings. $font_dir = array( From d391259432c8ce921f9477a5899b9a0e46559c7f Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Thu, 30 May 2024 16:55:36 -0700 Subject: [PATCH 08/11] Update src/wp-admin/includes/file.php Remove @see annotations. Not needed there. Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> --- src/wp-admin/includes/file.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index d1df1168f3523..3cf9c88584b60 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -787,8 +787,7 @@ function validate_file_to_edit( $file, $allowed_files = array() ) { * @type bool $test_type Whether to test that the mime type of the file is as expected. * @type string[] $mimes Array of allowed mime types keyed by their file extension regex. * @type string[] $upload_dir Array of the uploads directory data as returned by - * {@see wp_upload_dir()} or {@see wp_font_dir()}. If not set the function - * will use {@see wp_upload_dir()}. + * wp_upload_dir() or wp_font_dir(). Defaults to wp_upload_dir(). * } * @param string $time Time formatted in 'yyyy/mm'. * @param string $action Expected value for `$_POST['action']`. From 4bad2e34c1ee802d4dbc08561d268dd237195350 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Thu, 30 May 2024 18:29:36 -0700 Subject: [PATCH 09/11] Docs: Remove @see annotations. Not needed there. Props peterwilsoncc. --- src/wp-includes/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index c9e5d1e5e60cf..a1e2e57bde2e7 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -2873,8 +2873,8 @@ function _wp_check_existing_file_names( $filename, $files ) { * @param string $bits File content * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null. * @param string[] $upload_dir Optional. Array of the uploads directory data as returned by - * {@see wp_upload_dir()} or {@see wp_font_dir()}. If not set - * the function will use {@see wp_upload_dir()}. + * wp_upload_dir() or wp_font_dir(). If not set + * the function will use wp_upload_dir(). * @return array { * Information about the newly-uploaded file. * From 076854aa6641a226480865faa15800d44a957719 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Thu, 30 May 2024 18:46:20 -0700 Subject: [PATCH 10/11] Adjust the inline comment to match the changed code --- src/wp-includes/fonts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 6aad89f650f49..465208232ba3f 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -162,7 +162,7 @@ function wp_font_dir( $create_dir = true ) { */ $font_dir = apply_filters( 'font_dir', $font_dir, $upload_dir ); - // Do not attempt to create the /fonts directory if there was an error in wp_upload_dir() or after the 'font_dir' filter. + // Do not attempt to create the /fonts directory if an error was set while running the 'font_dir' filter. if ( ! empty( $font_dir['error'] ) ) { return $font_dir; } From f5b0d012ff7bf9bfe509c660d2d092908b833096 Mon Sep 17 00:00:00 2001 From: Andrew Ozz <743931+azaozz@users.noreply.github.com> Date: Fri, 31 May 2024 16:18:47 -0700 Subject: [PATCH 11/11] Add docs and some sanity checks when using custom upload_dir data. --- src/wp-admin/includes/file.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 3cf9c88584b60..f902fafc9e740 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -788,6 +788,8 @@ function validate_file_to_edit( $file, $allowed_files = array() ) { * @type string[] $mimes Array of allowed mime types keyed by their file extension regex. * @type string[] $upload_dir Array of the uploads directory data as returned by * wp_upload_dir() or wp_font_dir(). Defaults to wp_upload_dir(). + * If using custom data array the uploads directory must exist. + * See additional comments below. * } * @param string $time Time formatted in 'yyyy/mm'. * @param string $action Expected value for `$_POST['action']`. @@ -975,7 +977,27 @@ function wp_handle_upload_error( &$file, $message ) { } if ( isset( $overrides['upload_dir'] ) ) { + /* + * As mentioned in the description $overrides['upload_dir'] is expected to be an array + * of the uploads directory data as returned by wp_uploads_dir() and wp_fonts_dir(). + * + * It is possible to use custom data, however ensure the format matches exactly the array + * returned by the above fiunctions. In addition the uploads directory should exist and + * be accerssible before attempting to use it. For example that can be achieved + * by usig wp_mkdir_p(). This data can also be cached, however ensure any caching + * is reset after creating the directry. + */ $uploads = $overrides['upload_dir']; + + if ( ! is_array( $uploads ) || empty( $uploads['path'] ) || ! is_string( $uploads['path'] ) ) { + $uploads['error'] = __( 'The path to the uploads directory is incorrect.' ); + } elseif ( ! is_dir( $uploads['path'] ) ) { + $uploads['error'] = __( 'The uploads directory does not exist.' ); + } + + if ( ! empty( $uploads['error'] ) ) { + return call_user_func_array( $upload_error_handler, array( &$file, $uploads['error'] ) ); + } } else { $uploads = wp_upload_dir( $time ); }