From c2efdf175a438c151eab577c494b72ba49a1bb59 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Sat, 13 Sep 2025 00:25:32 +0530 Subject: [PATCH 1/5] Add `upload_url()` helper to retrieve the uploads directory URL --- src/wp-includes/link-template.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index cd9f42404487e..7cc8670b60b5a 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -3662,6 +3662,31 @@ function content_url( $path = '' ) { return apply_filters( 'content_url', $url, $path ); } +/** + * Retrieves the uploads directory URL. + * + * Returns either the base uploads URL (e.g. https://example.com/wp-content/uploads) + * or, when requested, the URL to the current time-based subdirectory + * (e.g. https://example.com/wp-content/uploads/2025/09) if year/month folders are enabled. + * + * This is a convenience wrapper around wp_upload_dir(). + * + * @since 6.9.0 + * + * @param bool $with_subdir Optional. Whether to include the time-based subdirectory + * when it is configured (mirrors wp_upload_dir()['url'] vs ['baseurl']). Default true. + * @return string Uploads URL. Empty string on failure. + */ +function upload_url( $with_subdir = true ) { + $uploads = wp_upload_dir(); + + if ( ! empty( $uploads['error'] ) ) { + return ''; + } + + return $with_subdir ? $uploads['url'] : $uploads['baseurl']; +} + /** * Retrieves a URL within the plugins or mu-plugins directory. * From 43efd7f2d8d8e9bea491b56c1c57f94811ca50d9 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Sat, 13 Sep 2025 00:27:29 +0530 Subject: [PATCH 2/5] Fix linting --- src/wp-includes/link-template.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 7cc8670b60b5a..41c0a32e98e75 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -3678,13 +3678,13 @@ function content_url( $path = '' ) { * @return string Uploads URL. Empty string on failure. */ function upload_url( $with_subdir = true ) { - $uploads = wp_upload_dir(); + $uploads = wp_upload_dir(); - if ( ! empty( $uploads['error'] ) ) { - return ''; - } + if ( ! empty( $uploads['error'] ) ) { + return ''; + } - return $with_subdir ? $uploads['url'] : $uploads['baseurl']; + return $with_subdir ? $uploads['url'] : $uploads['baseurl']; } /** From d1f9d38fc8579e9a62a05d384a4072cabf63fe82 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Sat, 13 Sep 2025 00:28:58 +0530 Subject: [PATCH 3/5] Improve the doc block comments --- src/wp-includes/link-template.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wp-includes/link-template.php b/src/wp-includes/link-template.php index 41c0a32e98e75..34484c9e5c7d9 100644 --- a/src/wp-includes/link-template.php +++ b/src/wp-includes/link-template.php @@ -3669,12 +3669,10 @@ function content_url( $path = '' ) { * or, when requested, the URL to the current time-based subdirectory * (e.g. https://example.com/wp-content/uploads/2025/09) if year/month folders are enabled. * - * This is a convenience wrapper around wp_upload_dir(). - * * @since 6.9.0 * * @param bool $with_subdir Optional. Whether to include the time-based subdirectory - * when it is configured (mirrors wp_upload_dir()['url'] vs ['baseurl']). Default true. + * when it is configured. Default true. * @return string Uploads URL. Empty string on failure. */ function upload_url( $with_subdir = true ) { From 6b0233971658382c6b9b2271278877c4c13d9066 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Mon, 15 Sep 2025 14:17:21 +0530 Subject: [PATCH 4/5] Tests: Add unit test for `upload_url()` function with default settings --- tests/phpunit/tests/upload.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/phpunit/tests/upload.php b/tests/phpunit/tests/upload.php index 46fcea7099097..bec8e97a8a1c2 100644 --- a/tests/phpunit/tests/upload.php +++ b/tests/phpunit/tests/upload.php @@ -105,4 +105,18 @@ public function test_upload_dir_empty() { $this->assertSame( $subdir, $info['subdir'] ); $this->assertFalse( $info['error'] ); } + + /** + * Tests the upload_url() function with default settings. + * + * @ticket 33963 + */ + public function test_upload_url() { + $expected = wp_upload_dir(); + $this->assertFalse( $expected['error'] ); + + $this->assertSame( $expected['url'], upload_url() ); + $this->assertSame( $expected['url'], upload_url( true ) ); + $this->assertSame( $expected['baseurl'], upload_url( false ) ); + } } From 619f39ea9c7059a3f4927c3958c66d7532dea1a0 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Mon, 15 Sep 2025 14:17:54 +0530 Subject: [PATCH 5/5] Tests: Add unit test for `upload_url()` function when year/month folders are disabled --- tests/phpunit/tests/upload.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/phpunit/tests/upload.php b/tests/phpunit/tests/upload.php index bec8e97a8a1c2..f50a949fd241a 100644 --- a/tests/phpunit/tests/upload.php +++ b/tests/phpunit/tests/upload.php @@ -119,4 +119,19 @@ public function test_upload_url() { $this->assertSame( $expected['url'], upload_url( true ) ); $this->assertSame( $expected['baseurl'], upload_url( false ) ); } + + /** + * Tests the upload_url() function when year/month folders are disabled. + * + * @ticket 33963 + */ + public function test_upload_url_without_yearmonth_folders() { + update_option( 'uploads_use_yearmonth_folders', 0 ); + + $expected = wp_upload_dir(); + + $this->assertFalse( $expected['error'] ); + $this->assertSame( $expected['url'], upload_url() ); + $this->assertSame( $expected['baseurl'], upload_url( false ) ); + } }