REST API: Add support for filename search in media endpoint.

In [38625], the functionality to search for attachments by filename was added
via the `posts_clauses` filter and the `_filter_query_attachment_filenames()`
function.  This moves `_filter_query_attachment_filenames()` from
`wp-admin/includes/post.php` to `wp-includes/post.php` so that it can be
applied in the same manner in the REST API media endpoint.

Props jblz, tyxla.
Fixes #39092.


git-svn-id: https://develop.svn.wordpress.org/trunk@39598 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
James Nylen 2016-12-13 14:08:24 +00:00
parent 03c947c7fd
commit 2642833293
4 changed files with 54 additions and 29 deletions

View File

@ -1154,35 +1154,6 @@ function wp_edit_attachments_query_vars( $q = false ) {
return $q;
}
/**
* Filter the SQL clauses of an attachment query to include filenames.
*
* @since 4.7.0
* @access private
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param array $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY,
* DISTINCT, fields (SELECT), and LIMITS clauses.
* @return array The modified clauses.
*/
function _filter_query_attachment_filenames( $clauses ) {
global $wpdb;
remove_filter( 'posts_clauses', __FUNCTION__ );
// Add a LEFT JOIN of the postmeta table so we don't trample existing JOINs.
$clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
$clauses['groupby'] = "{$wpdb->posts}.ID";
$clauses['where'] = preg_replace(
"/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
"$0 OR ( sq1.meta_value $1 $2 )",
$clauses['where'] );
return $clauses;
}
/**
* Executes a query for attachments. An array of WP_Query arguments
* can be passed in, which will override the arguments set by this function.

View File

@ -6188,3 +6188,32 @@ function wp_add_trashed_suffix_to_post_name_for_post( $post ) {
clean_post_cache( $post->ID );
return $post_name;
}
/**
* Filter the SQL clauses of an attachment query to include filenames.
*
* @since 4.7.0
* @access private
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param array $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY,
* DISTINCT, fields (SELECT), and LIMITS clauses.
* @return array The modified clauses.
*/
function _filter_query_attachment_filenames( $clauses ) {
global $wpdb;
remove_filter( 'posts_clauses', __FUNCTION__ );
// Add a LEFT JOIN of the postmeta table so we don't trample existing JOINs.
$clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
$clauses['groupby'] = "{$wpdb->posts}.ID";
$clauses['where'] = preg_replace(
"/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/",
"$0 OR ( sq1.meta_value $1 $2 )",
$clauses['where'] );
return $clauses;
}

View File

@ -47,6 +47,11 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
}
}
// Filter query clauses to include filenames.
if ( isset( $query_args['s'] ) ) {
add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
}
return $query_args;
}

View File

@ -1156,6 +1156,26 @@ class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control
$wp_rest_additional_fields = array();
}
public function test_search_item_by_filename() {
$id = $this->factory->attachment->create_object( $this->test_file, 0, array(
'post_mime_type' => 'image/jpeg',
) );
$id2 = $this->factory->attachment->create_object( $this->test_file2, 0, array(
'post_mime_type' => 'image/png',
) );
$filename = basename( $this->test_file2 );
$request = new WP_REST_Request( 'GET', '/wp/v2/media' );
$request->set_param( 'search', $filename );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertCount( 1, $data );
$this->assertEquals( $id2, $data[0]['id'] );
$this->assertEquals( 'image/png', $data[0]['mime_type'] );
}
public function additional_field_get_callback( $object, $request ) {
return 123;
}