Skip to content

Commit f6e37c0

Browse files
adamsilversteinclaude
authored andcommitted
REST API: Make filter_wp_unique_filename() static to match core, plus avoid duplicate routes (#75782)
* REST API: Make `filter_wp_unique_filename()` static to match core After WordPress/wordpress-develop#10868 (r61703), the core `WP_REST_Attachments_Controller::filter_wp_unique_filename()` method was changed to `private static`. This causes a fatal error in the Gutenberg subclass which declares it as non-static. Aligns the Gutenberg method signature with core by making it static and simplifying the parameters to match. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Avoid duplicate sideload route registration when core already has it Since core trunk now registers the sideload route in `WP_REST_Attachments_Controller::register_routes()`, only register it in the Gutenberg subclass when the parent class doesn't already have the `sideload_item` method. Updates the test accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3f5b13c commit f6e37c0

File tree

2 files changed

+42
-40
lines changed

2 files changed

+42
-40
lines changed

lib/media/class-gutenberg-rest-attachments-controller.php

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,41 @@ class Gutenberg_REST_Attachments_Controller extends WP_REST_Attachments_Controll
2020
public function register_routes(): void {
2121
parent::register_routes();
2222

23-
$valid_image_sizes = array_keys( wp_get_registered_image_subsizes() );
24-
25-
// Special case to set 'original_image' in attachment metadata.
26-
$valid_image_sizes[] = 'original';
27-
// Used for PDF thumbnails.
28-
$valid_image_sizes[] = 'full';
29-
30-
register_rest_route(
31-
$this->namespace,
32-
'/' . $this->rest_base . '/(?P<id>[\d]+)/sideload',
33-
array(
23+
// Only register the sideload route if the parent class doesn't already have it.
24+
if ( ! method_exists( get_parent_class( $this ), 'sideload_item' ) ) {
25+
$valid_image_sizes = array_keys( wp_get_registered_image_subsizes() );
26+
27+
// Special case to set 'original_image' in attachment metadata.
28+
$valid_image_sizes[] = 'original';
29+
// Used for PDF thumbnails.
30+
$valid_image_sizes[] = 'full';
31+
32+
register_rest_route(
33+
$this->namespace,
34+
'/' . $this->rest_base . '/(?P<id>[\d]+)/sideload',
3435
array(
35-
'methods' => WP_REST_Server::CREATABLE,
36-
'callback' => array( $this, 'sideload_item' ),
37-
'permission_callback' => array( $this, 'sideload_item_permissions_check' ),
38-
'args' => array(
39-
'id' => array(
40-
'description' => __( 'Unique identifier for the attachment.', 'gutenberg' ),
41-
'type' => 'integer',
42-
),
43-
'image_size' => array(
44-
'description' => __( 'Image size.', 'gutenberg' ),
45-
'type' => 'string',
46-
'enum' => $valid_image_sizes,
47-
'required' => true,
36+
array(
37+
'methods' => WP_REST_Server::CREATABLE,
38+
'callback' => array( $this, 'sideload_item' ),
39+
'permission_callback' => array( $this, 'sideload_item_permissions_check' ),
40+
'args' => array(
41+
'id' => array(
42+
'description' => __( 'Unique identifier for the attachment.', 'gutenberg' ),
43+
'type' => 'integer',
44+
),
45+
'image_size' => array(
46+
'description' => __( 'Image size.', 'gutenberg' ),
47+
'type' => 'string',
48+
'enum' => $valid_image_sizes,
49+
'required' => true,
50+
),
4851
),
4952
),
50-
),
51-
'allow_batch' => $this->allow_batch,
52-
'schema' => array( $this, 'get_public_item_schema' ),
53-
)
54-
);
53+
'allow_batch' => $this->allow_batch,
54+
'schema' => array( $this, 'get_public_item_schema' ),
55+
)
56+
);
57+
}
5558
}
5659

5760
/**
@@ -251,16 +254,14 @@ public function sideload_item_permissions_check( $request ) {
251254
*
252255
* @link https://github.com/WordPress/wordpress-develop/blob/30954f7ac0840cfdad464928021d7f380940c347/src/wp-includes/functions.php#L2576-L2582
253256
*
254-
* @param string $filename Unique file name.
255-
* @param string $ext File extension. Example: ".png".
256-
* @param string $dir Directory path.
257-
* @param callable|null $unique_filename_callback Callback function that generates the unique file name.
258-
* @param string[] $alt_filenames Array of alternate file names that were checked for collisions.
259-
* @param int|string $number The highest number that was used to make the file name unique
260-
* or an empty string if unused.
257+
* @param string $filename Unique file name.
258+
* @param string $dir Directory path.
259+
* @param int|string $number The highest number that was used to make the file name unique
260+
* or an empty string if unused.
261+
* @param string $attachment_filename Original attachment file name.
261262
* @return string Filtered file name.
262263
*/
263-
private function filter_wp_unique_filename( $filename, $ext, $dir, $unique_filename_callback, $alt_filenames, $number, $attachment_filename ) {
264+
private static function filter_wp_unique_filename( $filename, $dir, $number, $attachment_filename ) {
264265
if ( empty( $number ) || ! $attachment_filename ) {
265266
return $filename;
266267
}
@@ -338,8 +339,8 @@ public function sideload_item( WP_REST_Request $request ) {
338339
* or an empty string if unused.
339340
* @return string Filtered file name.
340341
*/
341-
$filter_filename = function ( $filename, $ext, $dir, $unique_filename_callback, $alt_filenames, $number ) use ( $attachment_filename ) {
342-
return $this->filter_wp_unique_filename( $filename, $ext, $dir, $unique_filename_callback, $alt_filenames, $number, $attachment_filename );
342+
$filter_filename = static function ( $filename, $ext, $dir, $unique_filename_callback, $alt_filenames, $number ) use ( $attachment_filename ) {
343+
return self::filter_wp_unique_filename( $filename, $dir, $number, $attachment_filename );
343344
};
344345

345346
add_filter( 'wp_unique_filename', $filter_filename, 10, 6 );

phpunit/media/class-gutenberg-rest-attachments-controller-test.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public function test_register_routes() {
4646
$this->assertArrayHasKey( '/wp/v2/media/(?P<id>[\d]+)', $routes );
4747
$this->assertCount( 3, $routes['/wp/v2/media/(?P<id>[\d]+)'] );
4848
$this->assertArrayHasKey( '/wp/v2/media/(?P<id>[\d]+)/sideload', $routes );
49-
$this->assertCount( 1, $routes['/wp/v2/media/(?P<id>[\d]+)/sideload'] );
49+
// Core may already register the sideload route; Gutenberg only adds it when core doesn't have it.
50+
$this->assertGreaterThanOrEqual( 1, count( $routes['/wp/v2/media/(?P<id>[\d]+)/sideload'] ) );
5051
}
5152

5253
public function test_get_items() {

0 commit comments

Comments
 (0)