diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php
index c4496dea3d403..830b564b91422 100644
--- a/src/wp-admin/includes/template.php
+++ b/src/wp-admin/includes/template.php
@@ -734,6 +734,7 @@ function meta_form( $post = null ) {
}
if ( $keys ) {
+ $keys = array_unique( $keys );
natcasesort( $keys );
}
?>
diff --git a/tests/phpunit/tests/admin/includesTemplate.php b/tests/phpunit/tests/admin/includesTemplate.php
index 6e8c9461c7e61..92dfcd4f43248 100644
--- a/tests/phpunit/tests/admin/includesTemplate.php
+++ b/tests/phpunit/tests/admin/includesTemplate.php
@@ -105,6 +105,45 @@ public function test_get_inline_data_contains_term_if_show_ui_is_false_but_show_
$this->expectOutputRegex( '/
Test<\/div>/' );
}
+ /**
+ * @ticket 54339
+ *
+ * @covers ::meta_form
+ */
+ public function test_meta_form_shows_each_filtered_key_once() {
+ wp_set_current_user( self::$editor_id );
+ $post = self::factory()->post->create_and_get();
+
+ add_filter(
+ 'postmeta_form_keys',
+ static function () {
+ return array( 'item10', 'CaseKey', 'shared', '_protected' );
+ }
+ );
+ add_filter(
+ 'postmeta_form_keys',
+ static function ( $keys ) {
+ return array_merge( $keys, array( 'shared', 'item2', 'casekey', 'denied' ) );
+ },
+ 20
+ );
+ add_filter( 'auth_post_meta_denied', '__return_false' );
+
+ ob_start();
+ meta_form( $post );
+ $output = ob_get_clean();
+
+ $processor = new WP_HTML_Tag_Processor( $output );
+ $keys = array();
+ while ( $processor->next_tag( 'OPTION' ) ) {
+ $keys[] = $processor->get_attribute( 'value' );
+ }
+
+ $this->assertContains( 'CaseKey', $keys );
+ $this->assertContains( 'casekey', $keys );
+ $this->assertSame( array( '#none#', 'casekey', 'casekey', 'item2', 'item10', 'shared' ), array_map( 'strtolower', $keys ) );
+ }
+
public function test_add_meta_box() {
global $wp_meta_boxes;