From c6844b30bc85f2d9fbe760a9b1adb4dd8d3f4c20 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Sun, 3 Mar 2024 11:39:45 +1100 Subject: [PATCH 01/29] Test naive filtering of uploads directory. --- .../tests/fonts/font-library/wpFontsDir.php | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index a8f79888315bd..0fd66778cd5a8 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -69,4 +69,39 @@ function set_new_values( $defaults ) { $this->assertSame( static::$dir_defaults, $font_dir, 'The wp_get_font_dir() method should return the default values.' ); } + + 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_get_font_dir' ); + + add_filter( + 'upload_dir', + function ( $upload_dir ) { + static $count = 0; + ++$count; + // It may be hit a couple of times, at five iterations assume an infinite loop. + $this->assertLessThan( 5, $count, 'Filtering uploads directory should not trigger infinite loop.' ); + return $upload_dir; + }, + 5 + ); + + /* + * Filter the font directory to return the uploads directory. + * + * The emulates a moving font files back to the uploads directory due + * to file system structure. + */ + add_filter( 'font_dir', 'wp_get_upload_dir' ); + + wp_get_upload_dir(); + + // This will never be hit if an infinite loop is triggered. + $this->assertTrue( true ); + } } From b64bfae6ef2e0d06225ae79af4629598b1bbd6b6 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Sun, 3 Mar 2024 11:49:38 +1100 Subject: [PATCH 02/29] Prevent infinite loop filtering fonts directory. Props @costdev. --- src/wp-includes/fonts.php | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 690aaa5ffc343..ea3424e73a14b 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -96,8 +96,11 @@ function wp_unregister_font_collection( string $slug ) { * * @since 6.5.0 * - * @return array $defaults { - * Array of information about the upload directory. + * @param array|null $font_dir Optional. Array of unfiltered uploads directory. + * This is used when the function is called from + * the upload_dir filter. Default null. + * @return array { + * Array of information about the font upload directory. * * @type string $path Base directory and subdirectory or full path to the fonts upload directory. * @type string $url Base URL and subdirectory or absolute URL to the fonts upload directory. @@ -107,13 +110,23 @@ function wp_unregister_font_collection( string $slug ) { * @type string|false $error False or error message. * } */ -function wp_get_font_dir() { +function wp_get_font_dir( $font_dir = null ) { + if ( doing_filter( 'font_dir' ) ) { + /* + * The font_dir filter is being run, avoid an infinite loop. + * + * This indicates that a plugin is calling wp_upload_dir() while filtering + * the font directory and avoids an infinite loop. + */ + return $font_dir; + } + $site_path = ''; if ( is_multisite() && ! ( is_main_network() && is_main_site() ) ) { $site_path = '/sites/' . get_current_blog_id(); } - $defaults = array( + $font_dir = array( 'path' => path_join( WP_CONTENT_DIR, 'fonts' ) . $site_path, 'url' => untrailingslashit( content_url( 'fonts' ) ) . $site_path, 'subdir' => '', @@ -129,9 +142,9 @@ function wp_get_font_dir() { * * @since 6.5.0 * - * @param array $defaults The original fonts directory data. + * @param array $font_dir The original fonts directory data. */ - return apply_filters( 'font_dir', $defaults ); + return apply_filters( 'font_dir', $font_dir ); } /** From c1edfbafdac9f0cc8056393e88217202b1bfce82 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:14:04 +1100 Subject: [PATCH 03/29] Restore naive filtering to rest end point. --- .../class-wp-rest-font-faces-controller.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) 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 3b3a338b838ec..46eeeccf31c46 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,21 +856,7 @@ 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' ) ); - - /* - * Set the upload directory to the fonts directory. - * - * wp_get_font_dir() contains the 'font_dir' hook, whose callbacks are - * likely to call wp_get_upload_dir(). - * - * To avoid an infinite loop, don't hook wp_get_font_dir() to 'upload_dir'. - * Instead, just pass its return value to the 'upload_dir' callback. - */ - $font_dir = wp_get_font_dir(); - $set_upload_dir = function () use ( $font_dir ) { - return $font_dir; - }; - add_filter( 'upload_dir', $set_upload_dir ); + add_filter( 'upload_dir', 'wp_get_font_dir' ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -888,7 +874,7 @@ protected function handle_font_file_upload( $file ) { $uploaded_file = wp_handle_upload( $file, $overrides ); - remove_filter( 'upload_dir', $set_upload_dir ); + remove_filter( 'upload_dir', 'wp_get_font_dir' ); remove_filter( 'upload_mimes', array( 'WP_Font_Utils', 'get_allowed_font_mime_types' ) ); return $uploaded_file; From 19cc1c71176e5f351ee8feca0e103426b2bc2904 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Wed, 6 Mar 2024 10:25:40 +1100 Subject: [PATCH 04/29] =?UTF-8?q?Thought=20bubble=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/wp-includes/fonts.php | 88 ++++++++++++------- .../class-wp-rest-font-faces-controller.php | 4 +- .../fonts/font-library/fontLibraryHooks.php | 4 +- .../tests/fonts/font-library/wpFontsDir.php | 2 +- 4 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index ea3424e73a14b..88a658bc2d9df 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -92,41 +92,65 @@ function wp_unregister_font_collection( string $slug ) { } /** - * Returns an array containing the current fonts upload directory's path and URL. + * Lightweight, don't create directory. * - * @since 6.5.0 + * @todo Get in a committable state if it's decided to do this. * - * @param array|null $font_dir Optional. Array of unfiltered uploads directory. - * This is used when the function is called from - * the upload_dir filter. Default null. - * @return array { - * Array of information about the font upload directory. - * - * @type string $path Base directory and subdirectory or full path to the fonts upload directory. - * @type string $url Base URL and subdirectory or absolute URL to the fonts upload directory. - * @type string $subdir Subdirectory - * @type string $basedir Path without subdir. - * @type string $baseurl URL path without subdir. - * @type string|false $error False or error message. - * } + * @return array + */ +function wp_get_font_dir() { + return wp_font_dir( false ); +} + +/** + * Get and create the font directory. + * + * @todo Get in a committable state if it's decided to do this. + * + * @param bool $create_dir + * @param bool $refresh_cache + * @return array + */ +function wp_font_dir( $create_dir = true, $refresh_cache = false ) { + // Allow extenders to manipulate the font directory consistently. + add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + $font_dir = wp_upload_dir( null, $create_dir, $refresh_cache ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + return $font_dir; +} + +/** + * Apply the filter. + * + * @todo Get in a committable state if it's decided to do this. + * + * @param mixed $font_dir + * @return mixed */ -function wp_get_font_dir( $font_dir = null ) { +function wp_apply_font_dir_filter( $font_dir ) { if ( doing_filter( 'font_dir' ) ) { - /* - * The font_dir filter is being run, avoid an infinite loop. - * - * This indicates that a plugin is calling wp_upload_dir() while filtering - * the font directory and avoids an infinite loop. - */ + // Avoid an infinite loop. return $font_dir; } + return apply_filters( 'font_dir', $font_dir ); +} + +/** + * Default font filter. + * + * @todo Get in a committable state if it's decided to do this. + * + * @param mixed $font_dir + * @return void + */ +function wp_default_font_dir_filter() { $site_path = ''; if ( is_multisite() && ! ( is_main_network() && is_main_site() ) ) { $site_path = '/sites/' . get_current_blog_id(); } - $font_dir = array( + return array( 'path' => path_join( WP_CONTENT_DIR, 'fonts' ) . $site_path, 'url' => untrailingslashit( content_url( 'fonts' ) ) . $site_path, 'subdir' => '', @@ -134,19 +158,15 @@ function wp_get_font_dir( $font_dir = null ) { 'baseurl' => untrailingslashit( content_url( 'fonts' ) ) . $site_path, 'error' => false, ); - - /** - * Filters the fonts directory data. - * - * This filter allows developers to modify the fonts directory data. - * - * @since 6.5.0 - * - * @param array $font_dir The original fonts directory data. - */ - return apply_filters( 'font_dir', $font_dir ); } +/* + * Runs early to allow extenders to hook on to the filter. + * + * @todo Move to default filters so it's in a committable state if it's decided to do this. + */ +add_filter( 'font_dir', 'wp_default_font_dir_filter', 5 ); + /** * Deletes child font faces when a font family is deleted. * 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 46eeeccf31c46..163c3d414c9e0 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,7 +856,7 @@ 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' ) ); - add_filter( 'upload_dir', 'wp_get_font_dir' ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -874,7 +874,7 @@ protected function handle_font_file_upload( $file ) { $uploaded_file = wp_handle_upload( $file, $overrides ); - remove_filter( 'upload_dir', 'wp_get_font_dir' ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); 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 083c12202aa34..9cf3cfd7706c0 100644 --- a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php +++ b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -73,13 +73,13 @@ 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_get_font_dir' ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); $font_file = wp_upload_bits( $font_filename, null, file_get_contents( $font_file_path ) ); - remove_filter( 'upload_dir', 'wp_get_font_dir' ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); 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 0fd66778cd5a8..6c5affa8c9fd2 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -77,7 +77,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { * This emulates the approach a plugin developer may take to * add the filter when extending the font library functionality. */ - add_filter( 'upload_dir', 'wp_get_font_dir' ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); add_filter( 'upload_dir', From a10dbe4f6ece3a3b9af17a55f0c1376926e6fee2 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:10:06 +1100 Subject: [PATCH 05/29] Improve comment. --- src/wp-includes/fonts.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 88a658bc2d9df..fe9c41b3f7c77 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -112,7 +112,13 @@ function wp_get_font_dir() { * @return array */ function wp_font_dir( $create_dir = true, $refresh_cache = false ) { - // Allow extenders to manipulate the font directory consistently. + /* + * Allow extenders to manipulate the font directory consistently. + * + * This ensures the upload_dir filter is fired both when using + * this function directly and when using the upload directory + * is filtered in the Font Face REST API endpoint. + */ add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); $font_dir = wp_upload_dir( null, $create_dir, $refresh_cache ); remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); From 2b21c6dd7643031365a65438633036d414ed0c4f Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:12:19 +1100 Subject: [PATCH 06/29] Move the font directory filter registration. --- src/wp-includes/default-filters.php | 2 ++ src/wp-includes/fonts.php | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 3f7e43f8615bc..17343df20415d 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -751,6 +751,8 @@ add_action( 'deleted_post', '_wp_after_delete_font_family', 10, 2 ); add_action( 'before_delete_post', '_wp_before_delete_font_face', 10, 2 ); add_action( 'init', '_wp_register_default_font_collections' ); +// Filter the font upload directory. Runs early to ensure the default directory is applied at priority 10 (default). +add_filter( 'font_dir', 'wp_default_font_dir_filter', 5 ); // It might be nice to use a filter instead of an action, but the `WP_REST_Templates_Controller` doesn't // provide one (unlike e.g. `WP_REST_Posts_Controller`, which has `rest_pre_insert_{$this->post_type}`). diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index fe9c41b3f7c77..7a9227a09d3c0 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -166,13 +166,6 @@ function wp_default_font_dir_filter() { ); } -/* - * Runs early to allow extenders to hook on to the filter. - * - * @todo Move to default filters so it's in a committable state if it's decided to do this. - */ -add_filter( 'font_dir', 'wp_default_font_dir_filter', 5 ); - /** * Deletes child font faces when a font family is deleted. * From ba51db258690a2a49c49865395ff615bb8e0ddbc Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:23:26 +1100 Subject: [PATCH 07/29] Remove cache option: N/A for fonts. --- 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 7a9227a09d3c0..ed7be2baadb05 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -111,7 +111,7 @@ function wp_get_font_dir() { * @param bool $refresh_cache * @return array */ -function wp_font_dir( $create_dir = true, $refresh_cache = false ) { +function wp_font_dir( $create_dir = true ) { /* * Allow extenders to manipulate the font directory consistently. * @@ -120,7 +120,7 @@ function wp_font_dir( $create_dir = true, $refresh_cache = false ) { * is filtered in the Font Face REST API endpoint. */ add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); - $font_dir = wp_upload_dir( null, $create_dir, $refresh_cache ); + $font_dir = wp_upload_dir( null, $create_dir, false ); remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); return $font_dir; } From d0ef78ea43b09158503fe13b97eb4ab6e8fe9f53 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:23:35 +1100 Subject: [PATCH 08/29] Docblocks. --- src/wp-includes/fonts.php | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index ed7be2baadb05..545f704f304c8 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -92,24 +92,38 @@ function wp_unregister_font_collection( string $slug ) { } /** - * Lightweight, don't create directory. + * Retrieves uploads directory information. * - * @todo Get in a committable state if it's decided to do this. + * Same as wp_font_dir() but "light weight" as it doesn't attempt to create the font uploads directory. + * Intended for use in themes, when only 'basedir' and 'baseurl' are needed, generally in all cases + * when not uploading files. + * + * @since 6.5.0 + * + * @see wp_font_dir() * - * @return array + * @return array See wp_font_dir() for description. */ function wp_get_font_dir() { return wp_font_dir( false ); } /** - * Get and create the font directory. + * Returns an array containing the current fonts upload directory's path and URL. * - * @todo Get in a committable state if it's decided to do this. + * @since 6.5.0 * - * @param bool $create_dir - * @param bool $refresh_cache - * @return array + * @param bool $create_dir Optional. Whether to check and create the font uploads directory. Default true. + * @return array $defaults { + * Array of information about the upload directory. + * + * @type string $path Base directory and subdirectory or full path to the fonts upload directory. + * @type string $url Base URL and subdirectory or absolute URL to the fonts upload directory. + * @type string $subdir Subdirectory + * @type string $basedir Path without subdir. + * @type string $baseurl URL path without subdir. + * @type string|false $error False or error message. + * } */ function wp_font_dir( $create_dir = true ) { /* From 327700200c639ea16fd7ce2e31cc85175e9050b4 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:27:48 +1100 Subject: [PATCH 09/29] Improve comment. --- src/wp-includes/fonts.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 545f704f304c8..1338b59a4a0e6 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -129,9 +129,9 @@ function wp_font_dir( $create_dir = true ) { /* * Allow extenders to manipulate the font directory consistently. * - * This ensures the upload_dir filter is fired both when using - * this function directly and when using the upload directory - * is filtered in the Font Face REST API endpoint. + * 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_apply_font_dir_filter' ); $font_dir = wp_upload_dir( null, $create_dir, false ); From db876de9c6b343a7e4dd8ec735330b00e2d6c9ec Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:34:13 +1100 Subject: [PATCH 10/29] More docblocks. --- src/wp-includes/fonts.php | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 1338b59a4a0e6..015201b554934 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -140,12 +140,15 @@ function wp_font_dir( $create_dir = true ) { } /** - * Apply the filter. + * Wrapper for apply_filters( 'font_dir', $font_dir ). * - * @todo Get in a committable state if it's decided to do this. + * Allows developers to manipulate the font directory used by the + * font library. * - * @param mixed $font_dir - * @return mixed + * @since 6.5.0 + * + * @param string $font_dir The font directory. + * @return string The modified font directory. */ function wp_apply_font_dir_filter( $font_dir ) { if ( doing_filter( 'font_dir' ) ) { @@ -157,12 +160,20 @@ function wp_apply_font_dir_filter( $font_dir ) { } /** - * Default font filter. + * Modify the default font directory. + * + * This function should not be called directly, use wp_get_font_dir() instead. + * + * Modifies the default font directory used by WordPress to the subdirectory fonts + * within the content directory. This function should not be called directly but + * rather applied to the {@see 'font_dir'} hook. * - * @todo Get in a committable state if it's decided to do this. + * @access private + * @since 6.5.0 * - * @param mixed $font_dir - * @return void + * @see wp_get_font_dir() + * + * @return array See wp_font_dir() for description. */ function wp_default_font_dir_filter() { $site_path = ''; From cec16c6e90f215fad880ead9e65ebf2440ee3ea8 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:32:30 +1100 Subject: [PATCH 11/29] Use static for closure. Co-authored-by: Mukesh Panchal --- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index 6c5affa8c9fd2..90a5eadfbdf29 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -81,7 +81,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { add_filter( 'upload_dir', - function ( $upload_dir ) { + static function ( $upload_dir ) { static $count = 0; ++$count; // It may be hit a couple of times, at five iterations assume an infinite loop. From 94c576bc4ff5b0f2e93aeb412653258dc6b27d7a Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:41:45 +1100 Subject: [PATCH 12/29] Revert "Use static for closure." This reverts commit cec16c6e90f215fad880ead9e65ebf2440ee3ea8. --- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index 90a5eadfbdf29..6c5affa8c9fd2 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -81,7 +81,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { add_filter( 'upload_dir', - static function ( $upload_dir ) { + function ( $upload_dir ) { static $count = 0; ++$count; // It may be hit a couple of times, at five iterations assume an infinite loop. From eff1763869878d9071dd2103fc647586d55fc22c Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 8 Mar 2024 14:16:42 +1100 Subject: [PATCH 13/29] Font uploads. --- 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 015201b554934..e05a934d71b8f 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -92,7 +92,7 @@ function wp_unregister_font_collection( string $slug ) { } /** - * Retrieves uploads directory information. + * Retrieves font uploads directory information. * * Same as wp_font_dir() but "light weight" as it doesn't attempt to create the font uploads directory. * Intended for use in themes, when only 'basedir' and 'baseurl' are needed, generally in all cases From 48aca491b180d3892725d35743eeadd311756c66 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:30:47 +1100 Subject: [PATCH 14/29] Dockblock improvements Co-authored-by: Colin Stewart <79332690+costdev@users.noreply.github.com> --- src/wp-includes/fonts.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index e05a934d71b8f..a85c8ac056517 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -140,7 +140,10 @@ function wp_font_dir( $create_dir = true ) { } /** + * Applies filters to manipulate the font directory used by the font library. + * * Wrapper for apply_filters( 'font_dir', $font_dir ). + * Does not apply filters if already doing the {@see 'font_dir'} filter. * * Allows developers to manipulate the font directory used by the * font library. @@ -160,7 +163,7 @@ function wp_apply_font_dir_filter( $font_dir ) { } /** - * Modify the default font directory. + * Modifies the default font directory. * * This function should not be called directly, use wp_get_font_dir() instead. * From 5117eef291bd58a9bd1eb1c104aaf0c77b0e91c3 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:33:46 +1100 Subject: [PATCH 15/29] Avoid duplicate assertions testing for loop. --- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index 6c5affa8c9fd2..d0c1ffedd1f7a 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -84,8 +84,10 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { function ( $upload_dir ) { static $count = 0; ++$count; - // It may be hit a couple of times, at five iterations assume an infinite loop. - $this->assertLessThan( 5, $count, 'Filtering uploads directory should not trigger infinite loop.' ); + // The filter may be applied a couple of times, at five iterations assume an infinite loop. + if ( $count >= 5 ) { + $this->fail( 'Filtering the uploads directory triggered an infinite loop.' ); + } return $upload_dir; }, 5 From 4b76a9cfa3ebe6643ccae67503eb8eb3c1a9c03b Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:35:20 +1100 Subject: [PATCH 16/29] Doc fix.: this not the. --- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index d0c1ffedd1f7a..2b86fba3cf55c 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -96,7 +96,7 @@ function ( $upload_dir ) { /* * Filter the font directory to return the uploads directory. * - * The emulates a moving font files back to the uploads directory due + * This emulates a moving font files back to the uploads directory due * to file system structure. */ add_filter( 'font_dir', 'wp_get_upload_dir' ); From addadc3b21ec0d8f039a18021c6235480c9b928b Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:38:58 +1100 Subject: [PATCH 17/29] Font upload, not upload dir. --- 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 a85c8ac056517..8687c43312805 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -115,7 +115,7 @@ function wp_get_font_dir() { * * @param bool $create_dir Optional. Whether to check and create the font uploads directory. Default true. * @return array $defaults { - * Array of information about the upload directory. + * Array of information about the font upload directory. * * @type string $path Base directory and subdirectory or full path to the fonts upload directory. * @type string $url Base URL and subdirectory or absolute URL to the fonts upload directory. From c1ac4e3b6d875cfa6193e966b04f5c02d8316e34 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Mon, 11 Mar 2024 08:39:10 +1100 Subject: [PATCH 18/29] Trolling? --- 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 8687c43312805..c3de6fd983e2f 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -141,7 +141,7 @@ function wp_font_dir( $create_dir = true ) { /** * Applies filters to manipulate the font directory used by the font library. - * + * * Wrapper for apply_filters( 'font_dir', $font_dir ). * Does not apply filters if already doing the {@see 'font_dir'} filter. * From 1c870cc5dd1b4a97253eb062f0127f6bcc5c8050 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:04:03 +1100 Subject: [PATCH 19/29] Rename function. --- src/wp-includes/default-filters.php | 2 +- src/wp-includes/fonts.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 2d7512a47fc60..3c99b52be2a78 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -752,7 +752,7 @@ add_action( 'before_delete_post', '_wp_before_delete_font_face', 10, 2 ); add_action( 'init', '_wp_register_default_font_collections' ); // Filter the font upload directory. Runs early to ensure the default directory is applied at priority 10 (default). -add_filter( 'font_dir', 'wp_default_font_dir_filter', 5 ); +add_filter( 'font_dir', 'wp_default_font_dir', 5 ); // Add ignoredHookedBlocks metadata attribute to the template and template part post types. add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes', 10, 2 ); diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index c3de6fd983e2f..1276b62fe4486 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -178,7 +178,7 @@ function wp_apply_font_dir_filter( $font_dir ) { * * @return array See wp_font_dir() for description. */ -function wp_default_font_dir_filter() { +function wp_default_font_dir() { $site_path = ''; if ( is_multisite() && ! ( is_main_network() && is_main_site() ) ) { $site_path = '/sites/' . get_current_blog_id(); From 1c3b7ac2da9af56c85c844928c6e024bbcf34039 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:09:36 +1100 Subject: [PATCH 20/29] Filter the font directory late. --- src/wp-includes/fonts.php | 4 ++-- .../endpoints/class-wp-rest-font-faces-controller.php | 4 ++-- tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php | 4 ++-- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 1276b62fe4486..cf37a2c9aaa26 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -133,9 +133,9 @@ function wp_font_dir( $create_dir = true ) { * directly and when the upload directory is filtered in the Font Face * REST API endpoint. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); $font_dir = wp_upload_dir( null, $create_dir, false ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); return $font_dir; } 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 163c3d414c9e0..ebb9d69ed8c1e 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,7 +856,7 @@ 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' ) ); - add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -874,7 +874,7 @@ protected function handle_font_file_upload( $file ) { $uploaded_file = wp_handle_upload( $file, $overrides ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); 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 9cf3cfd7706c0..b665dfd7841c5 100644 --- a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php +++ b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -73,13 +73,13 @@ 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_apply_font_dir_filter' ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); $font_file = wp_upload_bits( $font_filename, null, file_get_contents( $font_file_path ) ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); 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 2b86fba3cf55c..e4aaf45ee343a 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -77,7 +77,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { * This emulates the approach a plugin developer may take to * add the filter when extending the font library functionality. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filter' ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); add_filter( 'upload_dir', From fb2cfc36e1bc319582c1081813c3babbe26b2b4e Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:14:35 +1100 Subject: [PATCH 21/29] Document late running hook. --- src/wp-includes/fonts.php | 4 ++++ .../endpoints/class-wp-rest-font-faces-controller.php | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index cf37a2c9aaa26..93c0acf50767d 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -132,6 +132,10 @@ function wp_font_dir( $create_dir = true ) { * 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. + * + * The filter runs at priority 20 to ensure it runs after any filters + * added at the default priority by plugins modifying the upload path + * or URL. */ add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); $font_dir = wp_upload_dir( null, $create_dir, false ); 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 ebb9d69ed8c1e..5b8dea1b56286 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,6 +856,13 @@ 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.. + * + * The filter runs at priority 20 to ensure it runs after any filters + * added at the default priority by plugins modifying the upload path + * or URL. + */ add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); $overrides = array( From 52103f63b6905f3bcb980303b3bfa9905a58c9d2 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:10:10 +1100 Subject: [PATCH 22/29] Rename function to use plural filters. Co-authored-by: costdev --- src/wp-includes/fonts.php | 6 +++--- .../endpoints/class-wp-rest-font-faces-controller.php | 4 ++-- tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php | 4 ++-- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 93c0acf50767d..a2f27dde00d3e 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -137,9 +137,9 @@ function wp_font_dir( $create_dir = true ) { * added at the default priority by plugins modifying the upload path * or URL. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); $font_dir = wp_upload_dir( null, $create_dir, false ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); return $font_dir; } @@ -157,7 +157,7 @@ function wp_font_dir( $create_dir = true ) { * @param string $font_dir The font directory. * @return string The modified font directory. */ -function wp_apply_font_dir_filter( $font_dir ) { +function wp_apply_font_dir_filters( $font_dir ) { if ( doing_filter( 'font_dir' ) ) { // Avoid an infinite loop. return $font_dir; 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 c40313e8cc265..7807d42f3aff0 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 @@ -863,7 +863,7 @@ protected function handle_font_file_upload( $file ) { * added at the default priority by plugins modifying the upload path * or URL. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -880,7 +880,7 @@ protected function handle_font_file_upload( $file ) { $uploaded_file = wp_handle_upload( $file, $overrides ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); 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 b665dfd7841c5..0df6a47edcd1c 100644 --- a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php +++ b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -73,13 +73,13 @@ 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_apply_font_dir_filter', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); $font_file = wp_upload_bits( $font_filename, null, file_get_contents( $font_file_path ) ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); 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 e4aaf45ee343a..43fc7b1cacd20 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -77,7 +77,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { * This emulates the approach a plugin developer may take to * add the filter when extending the font library functionality. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filter', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); add_filter( 'upload_dir', From 21673e562876fda21d0b6edd21045bb6fe8f7f2a Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 14 Mar 2024 08:51:31 +1100 Subject: [PATCH 23/29] Remove a a typo. Co-authored-by: Colin Stewart <79332690+costdev@users.noreply.github.com> --- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index 43fc7b1cacd20..64c69e51b6fdb 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -96,7 +96,7 @@ function ( $upload_dir ) { /* * Filter the font directory to return the uploads directory. * - * This emulates a moving font files back to the uploads directory due + * This emulates moving font files back to the uploads directory due * to file system structure. */ add_filter( 'font_dir', 'wp_get_upload_dir' ); From 118313240685c1bf5c9ab3ca5f3f36b9db47897c Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 14 Mar 2024 09:34:19 +1100 Subject: [PATCH 24/29] Run filter at default priority. As the filter is created while getting the upload directory in `wp_upload_dir()` the core filter should be added after any plugins filter the uploads directory during the init or an earlier hook. --- src/wp-includes/fonts.php | 4 ++-- .../endpoints/class-wp-rest-font-faces-controller.php | 4 ++-- tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php | 4 ++-- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index a2f27dde00d3e..eeeb64cec7e56 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -137,9 +137,9 @@ function wp_font_dir( $create_dir = true ) { * added at the default priority by plugins modifying the upload path * or URL. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); $font_dir = wp_upload_dir( null, $create_dir, false ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); return $font_dir; } 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 7807d42f3aff0..7225e08b45247 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 @@ -863,7 +863,7 @@ protected function handle_font_file_upload( $file ) { * added at the default priority by plugins modifying the upload path * or URL. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -880,7 +880,7 @@ protected function handle_font_file_upload( $file ) { $uploaded_file = wp_handle_upload( $file, $overrides ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); 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 0df6a47edcd1c..a19784f6c10be 100644 --- a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php +++ b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -73,13 +73,13 @@ 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_apply_font_dir_filters', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); $font_file = wp_upload_bits( $font_filename, null, file_get_contents( $font_file_path ) ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); + remove_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); 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 64c69e51b6fdb..602cf5975c76e 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -77,7 +77,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { * This emulates the approach a plugin developer may take to * add the filter when extending the font library functionality. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filters', 20 ); + add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); add_filter( 'upload_dir', From 0204b99022a78a74b8bb81713a98ed6aa4cc7411 Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Sat, 16 Mar 2024 09:57:16 +1100 Subject: [PATCH 25/29] Remove out of date comment. --- src/wp-includes/fonts.php | 4 ---- .../endpoints/class-wp-rest-font-faces-controller.php | 8 +------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index eeeb64cec7e56..d6a6c55136361 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -132,10 +132,6 @@ function wp_font_dir( $create_dir = true ) { * 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. - * - * The filter runs at priority 20 to ensure it runs after any filters - * added at the default priority by plugins modifying the upload path - * or URL. */ add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); $font_dir = wp_upload_dir( null, $create_dir, false ); 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 7225e08b45247..8ea6e12326712 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,13 +856,7 @@ 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.. - * - * The filter runs at priority 20 to ensure it runs after any filters - * added at the default priority by plugins modifying the upload path - * or URL. - */ + // Filter the upload directory to return the fonts directory.. add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); $overrides = array( From eccdbac221f6747b14cff107591bbddeb99745ac Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:28:10 +1100 Subject: [PATCH 26/29] Merge default getter and filtering function. Rename. --- src/wp-includes/default-filters.php | 2 - src/wp-includes/fonts.php | 60 +++++++++---------- .../class-wp-rest-font-faces-controller.php | 6 +- .../fonts/font-library/fontLibraryHooks.php | 4 +- .../tests/fonts/font-library/wpFontsDir.php | 2 +- 5 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 3c99b52be2a78..884357f41350a 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -751,8 +751,6 @@ add_action( 'deleted_post', '_wp_after_delete_font_family', 10, 2 ); add_action( 'before_delete_post', '_wp_before_delete_font_face', 10, 2 ); add_action( 'init', '_wp_register_default_font_collections' ); -// Filter the font upload directory. Runs early to ensure the default directory is applied at priority 10 (default). -add_filter( 'font_dir', 'wp_default_font_dir', 5 ); // Add ignoredHookedBlocks metadata attribute to the template and template part post types. add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes', 10, 2 ); diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index d6a6c55136361..9a56a0fd6b5e5 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -114,7 +114,7 @@ function wp_get_font_dir() { * @since 6.5.0 * * @param bool $create_dir Optional. Whether to check and create the font uploads directory. Default true. - * @return array $defaults { + * @return array { * Array of information about the font upload directory. * * @type string $path Base directory and subdirectory or full path to the fonts upload directory. @@ -133,58 +133,36 @@ function wp_font_dir( $create_dir = true ) { * directly and when the upload directory is filtered in the Font Face * REST API endpoint. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); + add_filter( 'upload_dir', 'wp_filter_font_directory' ); $font_dir = wp_upload_dir( null, $create_dir, false ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); + remove_filter( 'upload_dir', 'wp_filter_font_directory' ); return $font_dir; } /** - * Applies filters to manipulate the font directory used by the font library. + * Returns the font directory for use by the font library. * - * Wrapper for apply_filters( 'font_dir', $font_dir ). - * Does not apply filters if already doing the {@see 'font_dir'} filter. - * - * Allows developers to manipulate the font directory used by the - * font library. + * This function is a callback for the 'upload_dir' filter. It is used not + * intended to be called directly. 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_apply_font_dir_filters( $font_dir ) { +function wp_filter_font_directory( $font_dir ) { if ( doing_filter( 'font_dir' ) ) { // Avoid an infinite loop. return $font_dir; } - return apply_filters( 'font_dir', $font_dir ); -} - -/** - * Modifies the default font directory. - * - * This function should not be called directly, use wp_get_font_dir() instead. - * - * Modifies the default font directory used by WordPress to the subdirectory fonts - * within the content directory. This function should not be called directly but - * rather applied to the {@see 'font_dir'} hook. - * - * @access private - * @since 6.5.0 - * - * @see wp_get_font_dir() - * - * @return array See wp_font_dir() for description. - */ -function wp_default_font_dir() { $site_path = ''; if ( is_multisite() && ! ( is_main_network() && is_main_site() ) ) { $site_path = '/sites/' . get_current_blog_id(); } - return array( + $font_dir = array( 'path' => path_join( WP_CONTENT_DIR, 'fonts' ) . $site_path, 'url' => untrailingslashit( content_url( 'fonts' ) ) . $site_path, 'subdir' => '', @@ -192,6 +170,26 @@ function wp_default_font_dir() { 'baseurl' => untrailingslashit( content_url( 'fonts' ) ) . $site_path, 'error' => false, ); + + /** + * Filters the fonts directory data. + * + * This filter allows developers to modify the fonts directory data. + * + * @since 6.5.0 + * + * @param array $font_dir { + * Array of information about the font upload directory. + * + * @type string $path Base directory and subdirectory or full path to the fonts upload directory. + * @type string $url Base URL and subdirectory or absolute URL to the fonts upload directory. + * @type string $subdir Subdirectory + * @type string $basedir Path without subdir. + * @type string $baseurl URL path without subdir. + * @type string|false $error False or error message. + * } + */ + return apply_filters( 'font_dir', $font_dir ); } /** 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 8ea6e12326712..c47de3e82d309 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,8 @@ 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_apply_font_dir_filters' ); + // Filter the upload directory to return the fonts directory. + add_filter( 'upload_dir', 'wp_filter_font_directory' ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -874,7 +874,7 @@ protected function handle_font_file_upload( $file ) { $uploaded_file = wp_handle_upload( $file, $overrides ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); + 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 a19784f6c10be..50e2c627b2362 100644 --- a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php +++ b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -73,13 +73,13 @@ 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_apply_font_dir_filters' ); + add_filter( 'upload_dir', 'wp_filter_font_directory' ); $font_file = wp_upload_bits( $font_filename, null, file_get_contents( $font_file_path ) ); - remove_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); + 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 602cf5975c76e..4c802792aff03 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -77,7 +77,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { * This emulates the approach a plugin developer may take to * add the filter when extending the font library functionality. */ - add_filter( 'upload_dir', 'wp_apply_font_dir_filters' ); + add_filter( 'upload_dir', 'wp_filter_font_directory' ); add_filter( 'upload_dir', From 22764e3650e38b56737f5f558d9a2125710b08dc Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 22 Mar 2024 10:21:10 +1100 Subject: [PATCH 27/29] Rename function. Props @swissspidy. --- src/wp-includes/fonts.php | 6 +++--- .../endpoints/class-wp-rest-font-faces-controller.php | 4 ++-- tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php | 4 ++-- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 9a56a0fd6b5e5..41f65b1341571 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -133,9 +133,9 @@ function wp_font_dir( $create_dir = true ) { * directly and when the upload directory is filtered in the Font Face * REST API endpoint. */ - add_filter( 'upload_dir', 'wp_filter_font_directory' ); + 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' ); + remove_filter( 'upload_dir', '_wp_filter_font_directory' ); return $font_dir; } @@ -151,7 +151,7 @@ function wp_font_dir( $create_dir = true ) { * @param string $font_dir The font directory. * @return string The modified font directory. */ -function wp_filter_font_directory( $font_dir ) { +function _wp_filter_font_directory( $font_dir ) { if ( doing_filter( 'font_dir' ) ) { // Avoid an infinite loop. return $font_dir; 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 c47de3e82d309..c7f72d4ec1d9d 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 @@ -857,7 +857,7 @@ 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' ); + add_filter( 'upload_dir', '_wp_filter_font_directory' ); $overrides = array( 'upload_error_handler' => array( $this, 'handle_font_file_upload_error' ), @@ -874,7 +874,7 @@ 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_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 50e2c627b2362..c288a1ae93845 100644 --- a/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php +++ b/tests/phpunit/tests/fonts/font-library/fontLibraryHooks.php @@ -73,13 +73,13 @@ 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' ); + add_filter( 'upload_dir', '_wp_filter_font_directory' ); $font_file = wp_upload_bits( $font_filename, null, file_get_contents( $font_file_path ) ); - remove_filter( 'upload_dir', 'wp_filter_font_directory' ); + 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 4c802792aff03..282393677b042 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -77,7 +77,7 @@ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { * 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', '_wp_filter_font_directory' ); add_filter( 'upload_dir', From cf211ae8117adbdc844ddd70bef04301c01c094f Mon Sep 17 00:00:00 2001 From: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com> Date: Fri, 22 Mar 2024 10:21:19 +1100 Subject: [PATCH 28/29] Document use of filter. --- src/wp-includes/fonts.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 41f65b1341571..74feee1ac9cf7 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -142,9 +142,19 @@ function wp_font_dir( $create_dir = true ) { /** * Returns the font directory for use by the font library. * - * This function is a callback for the 'upload_dir' filter. It is used not + * This function is a callback for the {@see 'upload_dir'} filter. It is not * intended to be called directly. Use wp_get_font_dir() instead. * + * The function can be used when extending the font library to modify the upload + * destination for font files via the upload_dir filter. The recommended way to + * do this is: + * + * ```php + * add_filter( 'upload_dir', '_wp_filter_font_directory' ); + * // Your code to upload or sideload a font file. + * remove_filter( 'upload_dir', '_wp_filter_font_directory' ); + * ``` + * * @since 6.5.0 * @access private * From 35f8e1bbcd2a33aee33d8e7b346d2fe5a19c29a9 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 22 Mar 2024 11:33:23 +0100 Subject: [PATCH 29/29] Add ticket reference --- tests/phpunit/tests/fonts/font-library/wpFontsDir.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php index 282393677b042..5021aefb59d95 100644 --- a/tests/phpunit/tests/fonts/font-library/wpFontsDir.php +++ b/tests/phpunit/tests/fonts/font-library/wpFontsDir.php @@ -70,6 +70,9 @@ function set_new_values( $defaults ) { $this->assertSame( static::$dir_defaults, $font_dir, 'The wp_get_font_dir() method should return the default values.' ); } + /** + * @ticket 60652 + */ public function test_fonts_dir_filters_do_not_trigger_infinite_loop() { /* * Naive filtering of uploads directory to return font directory.