diff --git a/src/wp-admin/includes/media.php b/src/wp-admin/includes/media.php
index 7cb942f1c945f..b1d073ebb0328 100644
--- a/src/wp-admin/includes/media.php
+++ b/src/wp-admin/includes/media.php
@@ -2869,12 +2869,11 @@ function media_upload_library_form( $errors ) {
get_results(
- "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
- FROM $wpdb->posts
- WHERE post_type = 'attachment'
- ORDER BY post_date DESC"
- );
+ /** This filter is documented in wp-includes/media.php */
+ $months = apply_filters( 'media_library_months_with_files', null );
+ if ( ! is_array( $months ) ) {
+ $months = wp_get_media_library_attachment_months();
+ }
$month_count = count( $months );
$selected_month = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php
index fd215c800f9dc..42196f8c12305 100644
--- a/src/wp-includes/media.php
+++ b/src/wp-includes/media.php
@@ -4883,16 +4883,9 @@ function wp_enqueue_media( $args = array() ) {
*/
$months = apply_filters( 'media_library_months_with_files', null );
if ( ! is_array( $months ) ) {
- $months = $wpdb->get_results(
- $wpdb->prepare(
- "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
- FROM $wpdb->posts
- WHERE post_type = %s
- ORDER BY post_date DESC",
- 'attachment'
- )
- );
+ $months = wp_get_media_library_attachment_months();
}
+
foreach ( $months as $month_year ) {
$month_year->text = sprintf(
/* translators: 1: Month, 2: Year. */
@@ -5152,6 +5145,37 @@ function wp_enqueue_media( $args = array() ) {
do_action( 'wp_enqueue_media' );
}
+/**
+ * Retrieves the months that have media library attachments.
+ *
+ * Example:
+ *
+ * $months = wp_get_media_library_attachment_months();
+ * $months === array(
+ * (object) array( 'year' => '2025', 'month' => '2' ),
+ * (object) array( 'year' => '2024', 'month' => '11' ),
+ * );
+ *
+ * @since tbd
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
+ * @return array Months with associated attachment post dates.
+ */
+function wp_get_media_library_attachment_months(): array {
+ global $wpdb;
+
+ return $wpdb->get_results(
+ $wpdb->prepare(
+ "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
+ FROM $wpdb->posts
+ WHERE post_type = %s
+ ORDER BY post_date DESC",
+ 'attachment'
+ )
+ );
+}
+
/**
* Retrieves media attached to the passed post.
*
diff --git a/tests/phpunit/tests/media/wpGetMediaLibraryAttachmentMonths.php b/tests/phpunit/tests/media/wpGetMediaLibraryAttachmentMonths.php
new file mode 100644
index 0000000000000..c5ad4d271a09f
--- /dev/null
+++ b/tests/phpunit/tests/media/wpGetMediaLibraryAttachmentMonths.php
@@ -0,0 +1,38 @@
+post->create(
+ array(
+ 'post_type' => 'attachment',
+ 'post_date' => '2025-03-15 00:00:00',
+ )
+ );
+ self::factory()->post->create(
+ array(
+ 'post_type' => 'attachment',
+ 'post_date' => '2024-11-01 00:00:00',
+ )
+ );
+
+ $months = wp_get_media_library_attachment_months();
+
+ $this->assertCount( 2, $months );
+ $this->assertSame( '2025', $months[0]->year );
+ $this->assertSame( '3', $months[0]->month );
+ $this->assertSame( '2024', $months[1]->year );
+ $this->assertSame( '11', $months[1]->month );
+ }
+}