WordPress.org

Make WordPress Core

Changeset 38625


Ignore:
Timestamp:
09/20/16 01:44:07 (9 months ago)
Author:
joemcgill
Message:

Media: Make media library searchable by filename.

This applies a new private function, _filter_query_attachment_filenames(),
to the post_clauses filter hook during wp_ajax_query_attachments() and
wp_edit_attachments_query_vars() to include _wp_attached_file post meta
in search queries performed from the media library or in a WP_Media_List_Table.

Props wonderboymusic, DrewAPicture, joemcgill, swissspidy.
Fixes #22744.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/ajax-actions.php

    r38490 r38625  
    23982398        $query['post_status'] .= ',private'; 
    23992399 
     2400    // Filter query clauses to include filenames. 
     2401    add_filter( 'posts_clauses', '_filter_query_attachment_filenames' ); 
     2402 
    24002403    /** 
    24012404     * Filters the arguments passed to WP_Query during an Ajax 
  • trunk/src/wp-admin/includes/post.php

    r38572 r38625  
    11451145    } 
    11461146 
     1147    // Filter query clauses to include filenames. 
     1148    add_filter( 'posts_clauses', '_filter_query_attachment_filenames' ); 
     1149 
    11471150    return $q; 
     1151} 
     1152 
     1153/** 
     1154 * Filter the SQL clauses of an attachment query to include filenames. 
     1155 * 
     1156 * @since 4.7.0 
     1157 * @access private 
     1158 * 
     1159 * @param array $clauses An array including WHERE, GROUP BY, JOIN, ORDER BY, 
     1160 *                       DISTINCT, fields (SELECT), and LIMITS clauses. 
     1161 * @return array The modified clauses. 
     1162 */ 
     1163function _filter_query_attachment_filenames( $clauses ) { 
     1164    global $wpdb; 
     1165    remove_filter( 'posts_clauses', __FUNCTION__ ); 
     1166 
     1167    $clauses['join'] = " INNER JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id )"; 
     1168    $clauses['groupby'] = "{$wpdb->posts}.ID"; 
     1169 
     1170    $clauses['where'] = preg_replace( 
     1171        "/\({$wpdb->posts}.post_content (NOT LIKE|LIKE) (\'[^']+\')\)/", 
     1172        "$0 OR ( {$wpdb->postmeta}.meta_key = '_wp_attached_file' AND {$wpdb->postmeta}.meta_value $1 $2 )", 
     1173        $clauses['where'] ); 
     1174 
     1175    return $clauses; 
    11481176} 
    11491177 
  • trunk/tests/phpunit/tests/query/search.php

    r37280 r38625  
    281281    } 
    282282 
     283    /** 
     284     * Unfiltered search queries for attachment post types should not inlcude 
     285     * filenames to ensure the postmeta JOINs don't happen on the front end. 
     286     * 
     287     * @ticket 22744 
     288     */ 
     289    public function test_exclude_file_names_in_attachment_search_by_default() { 
     290        $attachment = self::factory()->post->create( array( 
     291            'post_type'    => 'attachment', 
     292            'post_status'  => 'publish', 
     293            'post_title'   => 'bar foo', 
     294            'post_content' => 'foo bar', 
     295            'post_excerpt' => 'This post has foo', 
     296        ) ); 
     297 
     298        add_post_meta( $attachment, '_wp_attached_file', 'some-image2.png', true ); 
     299 
     300        // Pass post_type an array value. 
     301        $q = new WP_Query( array( 
     302            's'           => 'image2', 
     303            'fields'      => 'ids', 
     304            'post_type'   => 'attachment', 
     305            'post_status' => 'inherit', 
     306        ) ); 
     307 
     308        $this->assertNotEquals( array( $attachment ), $q->posts ); 
     309    } 
     310 
     311    /** 
     312     * @ticket 22744 
     313     */ 
     314    public function test_include_file_names_in_attachment_search_as_string() { 
     315        $attachment = self::factory()->post->create( array( 
     316            'post_type'    => 'attachment', 
     317            'post_status'  => 'publish', 
     318            'post_title'   => 'bar foo', 
     319            'post_content' => 'foo bar', 
     320            'post_excerpt' => 'This post has foo', 
     321        ) ); 
     322 
     323        add_post_meta( $attachment, '_wp_attached_file', 'some-image1.png', true ); 
     324        add_filter( 'posts_clauses', '_filter_query_attachment_filenames' ); 
     325 
     326        // Pass post_type a string value. 
     327        $q = new WP_Query( array( 
     328            's'           => 'image1', 
     329            'fields'      => 'ids', 
     330            'post_type'   => 'attachment', 
     331            'post_status' => 'inherit', 
     332        ) ); 
     333 
     334        $this->assertSame( array( $attachment ), $q->posts ); 
     335    } 
     336 
     337    /** 
     338     * @ticket 22744 
     339     */ 
     340    public function test_include_file_names_in_attachment_search_as_array() { 
     341        $attachment = self::factory()->post->create( array( 
     342            'post_type'    => 'attachment', 
     343            'post_status'  => 'publish', 
     344            'post_title'   => 'bar foo', 
     345            'post_content' => 'foo bar', 
     346            'post_excerpt' => 'This post has foo', 
     347        ) ); 
     348 
     349        add_post_meta( $attachment, '_wp_attached_file', 'some-image2.png', true ); 
     350        add_filter( 'posts_clauses', '_filter_query_attachment_filenames' ); 
     351 
     352        // Pass post_type an array value. 
     353        $q = new WP_Query( array( 
     354            's'           => 'image2', 
     355            'fields'      => 'ids', 
     356            'post_type'   => array( 'attachment' ), 
     357            'post_status' => 'inherit', 
     358        ) ); 
     359 
     360        $this->assertSame( array( $attachment ), $q->posts ); 
     361    } 
     362 
     363    /** 
     364     * @ticket 22744 
     365     */ 
     366    public function test_exclude_attachment_file_names_in_general_searches() { 
     367        $attachment = self::factory()->post->create( array( 
     368            'post_type'    => 'attachment', 
     369            'post_status'  => 'publish', 
     370            'post_title'   => 'bar foo', 
     371            'post_content' => 'foo bar', 
     372            'post_excerpt' => 'This post has foo', 
     373        ) ); 
     374 
     375        add_post_meta( $attachment, '_wp_attached_file', 'some-image3.png', true ); 
     376 
     377        $q = new WP_Query( array( 
     378            's'           => 'image3', 
     379            'fields'      => 'ids', 
     380            'post_type'   => array( 'post', 'page', 'attachment' ), 
     381            'post_status' => 'inherit', 
     382        ) ); 
     383 
     384        $this->assertNotEquals( array( $attachment ), $q->posts ); 
     385    } 
     386 
    283387    public function filter_posts_search( $sql ) { 
    284388        return $sql . ' /* posts_search */'; 
Note: See TracChangeset for help on using the changeset viewer.